Home | History | Annotate | Download | only in pdx
      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;
     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 
     48 template <ChannelHandleMode Mode>
     49 class 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 
     67 template <>
     68 class 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 
    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