1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_PDX_RPC_PAYLOAD_H_
2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_PDX_RPC_PAYLOAD_H_
3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <iterator>
5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/client.h>
7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/rpc/message_buffer.h>
8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/service.h>
9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android {
11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx {
12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace rpc {
13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Implements the payload interface, required by Serialize/Deserialize, on top
15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// of a thread-local MessageBuffer.
16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Slot>
17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass MessagePayload {
18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public:
19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  using BufferType = typename MessageBuffer<Slot>::BufferType;
20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  using ValueType = typename MessageBuffer<Slot>::ValueType;
21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Constructs a MessagePayload with an empty TLS buffer.
23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  MessagePayload()
24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      : buffer_(MessageBuffer<Slot>::GetEmptyBuffer()),
25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        cursor_(buffer_.begin()),
26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        const_cursor_(buffer_.cbegin()) {}
27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Returns a reference to the cursor iterator to be used during serialization
29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // into the underlying MessageBuffer.
30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  typename BufferType::iterator& Cursor() { return cursor_; }
31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Returns a reference to the const cursor iterator at the beginning of the
33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // underlying MessageBuffer.
34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  typename BufferType::const_iterator& ConstCursor() { return const_cursor_; }
35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Returns a const iterator marking the end of the underlying MessageBuffer.
37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  typename BufferType::const_iterator ConstEnd() { return buffer_.cend(); }
38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Resizes the underlying MessageBuffer and sets the cursor to the beginning.
40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void Resize(std::size_t size) {
41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    buffer_.resize(size);
42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    cursor_ = buffer_.begin();
43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const_cursor_ = buffer_.cbegin();
44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Resets the read cursor so that data can be read from the buffer again.
47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void Rewind() { const_cursor_ = buffer_.cbegin(); }
48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Adds |size| bytes to the size of the underlying MessageBuffer and positions
50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // the cursor at the beginning of the extended region.
51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void Extend(std::size_t size) {
52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const std::size_t offset = buffer_.size();
53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    buffer_.resize(offset + size);
54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    cursor_ = buffer_.begin() + offset;
55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const_cursor_ = buffer_.cbegin() + offset;
56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Clears the underlying MessageBuffer and sets the cursor to the beginning.
59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void Clear() {
60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    buffer_.clear();
61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    cursor_ = buffer_.begin();
62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const_cursor_ = buffer_.cbegin();
63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ValueType* Data() { return buffer_.data(); }
66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const ValueType* Data() const { return buffer_.data(); }
67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t Size() const { return buffer_.size(); }
68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t Capacity() const { return buffer_.capacity(); }
69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private:
71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  BufferType& buffer_;
72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  typename BufferType::iterator cursor_;
73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  typename BufferType::const_iterator const_cursor_;
74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  MessagePayload(const MessagePayload<Slot>&) = delete;
76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void operator=(const MessagePayload<Slot>&) = delete;
77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Implements the payload interface for service-side RPCs. Handles translating
80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// between remote and local handle spaces automatically.
81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Slot>
82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass ServicePayload : public MessagePayload<Slot>,
83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                       public MessageWriter,
84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                       public MessageReader {
85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public:
86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ServicePayload(Message& message) : message_(message) {}
87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // MessageWriter
89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void* GetNextWriteBufferSection(size_t size) override {
90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    this->Extend(size);
91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return &*this->Cursor();
92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  OutputResourceMapper* GetOutputResourceMapper() override { return &message_; }
95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // MessageReader
97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  BufferSection GetNextReadBufferSection() override {
98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return {&*this->ConstCursor(), &*this->ConstEnd()};
99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void ConsumeReadBufferSectionData(const void* new_start) override {
102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::advance(this->ConstCursor(),
103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                 PointerDistance(new_start, &*this->ConstCursor()));
104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  InputResourceMapper* GetInputResourceMapper() override { return &message_; }
107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private:
109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  Message& message_;
110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Implements the payload interface for client-side RPCs. Handles gathering file
113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// handles to be sent over IPC automatically.
114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Slot>
115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass ClientPayload : public MessagePayload<Slot>,
116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                      public MessageWriter,
117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                      public MessageReader {
118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public:
119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  using ContainerType =
120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      MessageBuffer<ThreadLocalTypeSlot<ClientPayload<Slot>>, 1024u, int>;
121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  using BufferType = typename ContainerType::BufferType;
122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ClientPayload(Transaction& transaction) : transaction_{transaction} {}
124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // MessageWriter
126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void* GetNextWriteBufferSection(size_t size) override {
127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    this->Extend(size);
128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return &*this->Cursor();
129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  OutputResourceMapper* GetOutputResourceMapper() override {
132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return &transaction_;
133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // MessageReader
136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  BufferSection GetNextReadBufferSection() override {
137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return {&*this->ConstCursor(), &*this->ConstEnd()};
138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void ConsumeReadBufferSectionData(const void* new_start) override {
141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::advance(this->ConstCursor(),
142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                 PointerDistance(new_start, &*this->ConstCursor()));
143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  InputResourceMapper* GetInputResourceMapper() override {
146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return &transaction_;
147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private:
150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  Transaction& transaction_;
151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace rpc
154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace pdx
155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace android
156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif  // ANDROID_PDX_RPC_PAYLOAD_H_
158