1#ifndef ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_
2#define ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_
3
4#include <memory>
5#include <string>
6#include <unordered_map>
7
8#include <hardware/gralloc.h>
9#include <pdx/service.h>
10#include <private/dvr/bufferhub_rpc.h>
11
12namespace android {
13namespace dvr {
14
15class BufferHubService;
16class ConsumerChannel;
17class ProducerChannel;
18class ConsumerQueueChannel;
19class ProducerQueueChannel;
20
21class BufferHubChannel : public pdx::Channel {
22 public:
23  enum ChannelType {
24    kProducerType,
25    kConsumerType,
26    kProducerQueueType,
27    kConsumerQueueType,
28  };
29
30  enum : int { kDetachedId = -1 };
31
32  BufferHubChannel(BufferHubService* service, int buffer_id, int channel_id,
33                   ChannelType channel_type)
34      : service_(service),
35        buffer_id_(buffer_id),
36        channel_id_(channel_id),
37        channel_type_(channel_type) {}
38  virtual ~BufferHubChannel() {}
39
40  virtual bool HandleMessage(pdx::Message& message) = 0;
41  virtual void HandleImpulse(pdx::Message& message) = 0;
42
43  // Captures buffer info for use by BufferHubService::DumpState().
44  struct BufferInfo {
45    // Common data field shared by BufferProducer and ProducerQueue.
46    int id = -1;
47    int type = -1;
48    size_t consumer_count = 0;
49
50    // Data field for buffer producer.
51    uint32_t width = 0;
52    uint32_t height = 0;
53    uint32_t layer_count = 0;
54    uint32_t format = 0;
55    uint64_t usage = 0;
56    std::string name;
57
58    // Data filed for producer queue.
59    size_t capacity = 0;
60    UsagePolicy usage_policy{0, 0, 0, 0};
61
62    BufferInfo(int id, size_t consumer_count, uint32_t width, uint32_t height,
63               uint32_t layer_count, uint32_t format, uint64_t usage, const std::string& name)
64        : id(id),
65          type(kProducerType),
66          consumer_count(consumer_count),
67          width(width),
68          height(height),
69          layer_count(layer_count),
70          format(format),
71          usage(usage),
72          name(name) {}
73
74    BufferInfo(int id, size_t consumer_count, size_t capacity,
75               const UsagePolicy& usage_policy)
76        : id(id),
77          type(kProducerQueueType),
78          consumer_count(consumer_count),
79          capacity(capacity),
80          usage_policy(usage_policy) {}
81
82    BufferInfo() {}
83  };
84
85  // Returns the buffer info for this buffer.
86  virtual BufferInfo GetBufferInfo() const = 0;
87
88  // Signal the client fd that an ownership change occurred using POLLIN.
89  void SignalAvailable();
90
91  // Clear the ownership change event.
92  void ClearAvailable();
93
94  // Signal hangup event.
95  void Hangup();
96
97  BufferHubService* service() const { return service_; }
98  ChannelType channel_type() const { return channel_type_; }
99  int buffer_id() const { return buffer_id_; }
100
101  int channel_id() const { return channel_id_; }
102  bool IsDetached() const { return channel_id_ == kDetachedId; }
103
104  void Detach() {
105    if (channel_type_ == kProducerType)
106      channel_id_ = kDetachedId;
107  }
108  void Attach(int channel_id) {
109    if (channel_type_ == kProducerType && channel_id_ == kDetachedId)
110      channel_id_ = channel_id;
111  }
112
113 private:
114  BufferHubService* service_;
115
116  // Static id of the buffer for logging and informational purposes. This id
117  // does not change for the life of the buffer.
118  // TODO(eieio): Consider using an id allocator instead of the originating
119  // channel id; channel ids wrap after 2^31 ids, but this is not a problem in
120  // general because channel ids are not used for any lookup in this service.
121  int buffer_id_;
122
123  // The channel id of the buffer. This may change for a persistent producer
124  // buffer if it is detached and re-attached to another channel.
125  int channel_id_;
126
127  ChannelType channel_type_;
128
129  BufferHubChannel(const BufferHubChannel&) = delete;
130  void operator=(const BufferHubChannel&) = delete;
131};
132
133class BufferHubService : public pdx::ServiceBase<BufferHubService> {
134 public:
135  BufferHubService();
136  ~BufferHubService() override;
137
138  pdx::Status<void> HandleMessage(pdx::Message& message) override;
139  void HandleImpulse(pdx::Message& message) override;
140
141  void OnChannelClose(pdx::Message& message,
142                      const std::shared_ptr<pdx::Channel>& channel) override;
143
144  bool IsInitialized() const override;
145  std::string DumpState(size_t max_length) override;
146
147  bool AddNamedBuffer(const std::string& name,
148                      const std::shared_ptr<ProducerChannel>& buffer);
149  std::shared_ptr<ProducerChannel> GetNamedBuffer(const std::string& name);
150  bool RemoveNamedBuffer(const ProducerChannel& buffer);
151
152 private:
153  friend BASE;
154
155  std::unordered_map<std::string, std::shared_ptr<ProducerChannel>>
156      named_buffers_;
157
158  pdx::Status<void> OnCreateBuffer(pdx::Message& message, uint32_t width,
159                                   uint32_t height, uint32_t format,
160                                   uint64_t usage, size_t meta_size_bytes);
161  pdx::Status<void> OnCreatePersistentBuffer(pdx::Message& message,
162                                             const std::string& name,
163                                             int user_id, int group_id,
164                                             uint32_t width, uint32_t height,
165                                             uint32_t format, uint64_t usage,
166                                             size_t meta_size_bytes);
167  pdx::Status<void> OnGetPersistentBuffer(pdx::Message& message,
168                                          const std::string& name);
169  pdx::Status<QueueInfo> OnCreateProducerQueue(pdx::Message& message,
170                                               size_t meta_size_bytes,
171                                               const UsagePolicy& usage_policy);
172
173  BufferHubService(const BufferHubService&) = delete;
174  void operator=(const BufferHubService&) = delete;
175};
176
177}  // namespace dvr
178}  // namespace android
179
180#endif  // ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_
181