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