1 #ifndef ANDROID_PDX_CHANNEL_HANDLE_H_ 2 #define ANDROID_PDX_CHANNEL_HANDLE_H_ 3 #include <cstdint> 4 #include <type_traits> 5 namespace android { 6 namespace pdx { 7 enum class ChannelHandleMode { 8 Local, 9 Borrowed, 10 Remote, 11 }; 12 class ChannelManagerInterface { 13 public: CloseHandle(std::int32_t handle)14 virtual void CloseHandle(std::int32_t handle) { } 15 virtual ~ChannelManagerInterface() = default; 16 }; 17 class ChannelHandleBase { 18 public: 19 ChannelHandleBase() = default; ChannelHandleBase(const int32_t & value)20 explicit ChannelHandleBase(const int32_t& value) : value_{value} {} 21 ChannelHandleBase(const ChannelHandleBase&) = delete; 22 ChannelHandleBase& operator=(const ChannelHandleBase&) = delete; value()23 std::int32_t value() const { return value_; } valid()24 bool valid() const { return value_ >= 0; } 25 explicit operator bool() const { return valid(); } Close()26 void Close() { value_ = kEmptyHandle; } 27 protected: 28 // Must not be used by itself. Must be derived from. 29 ~ChannelHandleBase() = default; 30 enum : std::int32_t { kEmptyHandle = -1 }; 31 std::int32_t value_{kEmptyHandle}; 32 }; 33 template <ChannelHandleMode Mode> 34 class ChannelHandle : public ChannelHandleBase { 35 public: 36 ChannelHandle() = default; 37 using ChannelHandleBase::ChannelHandleBase; ChannelHandle(ChannelHandle && other)38 ChannelHandle(ChannelHandle&& other) noexcept : ChannelHandleBase{other.value_} { 39 other.value_ = kEmptyHandle; 40 } 41 ~ChannelHandle() = default; Duplicate()42 ChannelHandle Duplicate() const { return ChannelHandle{value_}; } 43 ChannelHandle& operator=(ChannelHandle&& other) noexcept { 44 value_ = other.value_; 45 other.value_ = kEmptyHandle; 46 return *this; 47 } 48 }; 49 template <> 50 class ChannelHandle<ChannelHandleMode::Local> : public ChannelHandleBase { 51 public: 52 ChannelHandle() = default; ChannelHandle(ChannelManagerInterface * manager,int32_t value)53 ChannelHandle(ChannelManagerInterface* manager, int32_t value) 54 : ChannelHandleBase{value}, manager_{manager} {} 55 ChannelHandle(const ChannelHandle&) = delete; 56 ChannelHandle& operator=(const ChannelHandle&) = delete; ChannelHandle(ChannelHandle && other)57 ChannelHandle(ChannelHandle&& other) noexcept 58 : ChannelHandleBase{other.value_}, manager_{other.manager_} { 59 other.manager_ = nullptr; 60 other.value_ = kEmptyHandle; 61 } 62 ChannelHandle& operator=(ChannelHandle&& other) noexcept { 63 value_ = other.value_; 64 manager_ = other.manager_; 65 other.value_ = kEmptyHandle; 66 other.manager_ = nullptr; 67 return *this; 68 } ~ChannelHandle()69 ~ChannelHandle() { 70 if (manager_) 71 manager_->CloseHandle(value_); 72 } Borrow()73 ChannelHandle<ChannelHandleMode::Borrowed> Borrow() const { 74 return ChannelHandle<ChannelHandleMode::Borrowed>{value_}; 75 } Close()76 void Close() { 77 if (manager_) 78 manager_->CloseHandle(value_); 79 manager_ = nullptr; 80 value_ = kEmptyHandle; 81 } 82 private: 83 ChannelManagerInterface* manager_{nullptr}; 84 }; 85 using LocalChannelHandle = ChannelHandle<ChannelHandleMode::Local>; 86 using BorrowedChannelHandle = ChannelHandle<ChannelHandleMode::Borrowed>; 87 using RemoteChannelHandle = ChannelHandle<ChannelHandleMode::Remote>; 88 // ChannelReference is a 32 bit integer used in IPC serialization to be 89 // transferred across processes. You can convert this value to a local channel 90 // handle by calling Transaction.GetChannelHandle(). 91 using ChannelReference = int32_t; 92 } // namespace pdx 93 } // namespace android 94 #endif // ANDROID_PDX_CHANNEL_HANDLE_H_ 95