1#ifndef ANDROID_PDX_CHANNEL_HANDLE_H_ 2#define ANDROID_PDX_CHANNEL_HANDLE_H_ 3 4#include <cstdint> 5#include <type_traits> 6 7namespace android { 8namespace pdx { 9 10enum class ChannelHandleMode { 11 Local, 12 Borrowed, 13 Remote, 14}; 15 16class 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 26class ChannelHandleBase { 27 public: 28 ChannelHandleBase() = default; 29 ChannelHandleBase(const int32_t& value) : value_{value} {} 30 31 ChannelHandleBase(const ChannelHandleBase&) = delete; 32 ChannelHandleBase& operator=(const ChannelHandleBase&) = delete; 33 34 std::int32_t value() const { return value_; } 35 bool valid() const { return value_ >= 0; } 36 explicit operator bool() const { return valid(); } 37 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 48template <ChannelHandleMode Mode> 49class ChannelHandle : public ChannelHandleBase { 50 public: 51 ChannelHandle() = default; 52 using ChannelHandleBase::ChannelHandleBase; 53 ChannelHandle(ChannelHandle&& other) : ChannelHandleBase{other.value_} { 54 other.value_ = kEmptyHandle; 55 } 56 ~ChannelHandle() = default; 57 58 ChannelHandle Duplicate() const { return ChannelHandle{value_}; } 59 60 ChannelHandle& operator=(ChannelHandle&& other) { 61 value_ = other.value_; 62 other.value_ = kEmptyHandle; 63 return *this; 64 } 65}; 66 67template <> 68class ChannelHandle<ChannelHandleMode::Local> : public ChannelHandleBase { 69 public: 70 ChannelHandle() = default; 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 77 ChannelHandle(ChannelHandle&& other) 78 : ChannelHandleBase{other.value_}, manager_{other.manager_} { 79 other.manager_ = nullptr; 80 other.value_ = kEmptyHandle; 81 } 82 83 ChannelHandle& operator=(ChannelHandle&& other) { 84 value_ = other.value_; 85 manager_ = other.manager_; 86 other.value_ = kEmptyHandle; 87 other.manager_ = nullptr; 88 return *this; 89 } 90 91 ~ChannelHandle() { 92 if (manager_) 93 manager_->CloseHandle(value_); 94 } 95 96 ChannelHandle<ChannelHandleMode::Borrowed> Borrow() const { 97 return ChannelHandle<ChannelHandleMode::Borrowed>{value_}; 98 } 99 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 111using LocalChannelHandle = ChannelHandle<ChannelHandleMode::Local>; 112using BorrowedChannelHandle = ChannelHandle<ChannelHandleMode::Borrowed>; 113using 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(). 118using ChannelReference = int32_t; 119 120} // namespace pdx 121} // namespace android 122 123#endif // ANDROID_PDX_CHANNEL_HANDLE_H_ 124