|  | #ifndef ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_ | 
|  | #define ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_ | 
|  |  | 
|  | #include <memory> | 
|  | #include <string> | 
|  | #include <unordered_map> | 
|  |  | 
|  | #include <hardware/gralloc.h> | 
|  | #include <pdx/service.h> | 
|  | #include <private/dvr/bufferhub_rpc.h> | 
|  |  | 
|  | namespace android { | 
|  | namespace dvr { | 
|  |  | 
|  | class BufferHubService; | 
|  | class ConsumerChannel; | 
|  | class ProducerChannel; | 
|  | class ConsumerQueueChannel; | 
|  | class ProducerQueueChannel; | 
|  |  | 
|  | class BufferHubChannel : public pdx::Channel { | 
|  | public: | 
|  | enum ChannelType { | 
|  | kProducerType, | 
|  | kConsumerType, | 
|  | kProducerQueueType, | 
|  | kConsumerQueueType, | 
|  | }; | 
|  |  | 
|  | enum : int { kDetachedId = -1 }; | 
|  |  | 
|  | BufferHubChannel(BufferHubService* service, int buffer_id, int channel_id, | 
|  | ChannelType channel_type) | 
|  | : service_(service), | 
|  | buffer_id_(buffer_id), | 
|  | channel_id_(channel_id), | 
|  | channel_type_(channel_type) {} | 
|  | virtual ~BufferHubChannel() {} | 
|  |  | 
|  | virtual bool HandleMessage(pdx::Message& message) = 0; | 
|  | virtual void HandleImpulse(pdx::Message& message) = 0; | 
|  |  | 
|  | // Captures buffer info for use by BufferHubService::DumpState(). | 
|  | struct BufferInfo { | 
|  | // Common data field shared by BufferProducer and ProducerQueue. | 
|  | int id = -1; | 
|  | int type = -1; | 
|  | size_t consumer_count = 0; | 
|  |  | 
|  | // Data field for buffer producer. | 
|  | uint32_t width = 0; | 
|  | uint32_t height = 0; | 
|  | uint32_t layer_count = 0; | 
|  | uint32_t format = 0; | 
|  | uint64_t usage = 0; | 
|  | std::string name; | 
|  |  | 
|  | // Data filed for producer queue. | 
|  | size_t capacity = 0; | 
|  | UsagePolicy usage_policy{0, 0, 0, 0}; | 
|  |  | 
|  | BufferInfo(int id, size_t consumer_count, uint32_t width, uint32_t height, | 
|  | uint32_t layer_count, uint32_t format, uint64_t usage, const std::string& name) | 
|  | : id(id), | 
|  | type(kProducerType), | 
|  | consumer_count(consumer_count), | 
|  | width(width), | 
|  | height(height), | 
|  | layer_count(layer_count), | 
|  | format(format), | 
|  | usage(usage), | 
|  | name(name) {} | 
|  |  | 
|  | BufferInfo(int id, size_t consumer_count, size_t capacity, | 
|  | const UsagePolicy& usage_policy) | 
|  | : id(id), | 
|  | type(kProducerQueueType), | 
|  | consumer_count(consumer_count), | 
|  | capacity(capacity), | 
|  | usage_policy(usage_policy) {} | 
|  |  | 
|  | BufferInfo() {} | 
|  | }; | 
|  |  | 
|  | // Returns the buffer info for this buffer. | 
|  | virtual BufferInfo GetBufferInfo() const = 0; | 
|  |  | 
|  | // Signal the client fd that an ownership change occurred using POLLIN. | 
|  | void SignalAvailable(); | 
|  |  | 
|  | // Clear the ownership change event. | 
|  | void ClearAvailable(); | 
|  |  | 
|  | // Signal hangup event. | 
|  | void Hangup(); | 
|  |  | 
|  | BufferHubService* service() const { return service_; } | 
|  | ChannelType channel_type() const { return channel_type_; } | 
|  | int buffer_id() const { return buffer_id_; } | 
|  |  | 
|  | int channel_id() const { return channel_id_; } | 
|  | bool IsDetached() const { return channel_id_ == kDetachedId; } | 
|  |  | 
|  | void Detach() { | 
|  | if (channel_type_ == kProducerType) | 
|  | channel_id_ = kDetachedId; | 
|  | } | 
|  | void Attach(int channel_id) { | 
|  | if (channel_type_ == kProducerType && channel_id_ == kDetachedId) | 
|  | channel_id_ = channel_id; | 
|  | } | 
|  |  | 
|  | private: | 
|  | BufferHubService* service_; | 
|  |  | 
|  | // Static id of the buffer for logging and informational purposes. This id | 
|  | // does not change for the life of the buffer. | 
|  | // TODO(eieio): Consider using an id allocator instead of the originating | 
|  | // channel id; channel ids wrap after 2^31 ids, but this is not a problem in | 
|  | // general because channel ids are not used for any lookup in this service. | 
|  | int buffer_id_; | 
|  |  | 
|  | // The channel id of the buffer. This may change for a persistent producer | 
|  | // buffer if it is detached and re-attached to another channel. | 
|  | int channel_id_; | 
|  |  | 
|  | ChannelType channel_type_; | 
|  |  | 
|  | BufferHubChannel(const BufferHubChannel&) = delete; | 
|  | void operator=(const BufferHubChannel&) = delete; | 
|  | }; | 
|  |  | 
|  | class BufferHubService : public pdx::ServiceBase<BufferHubService> { | 
|  | public: | 
|  | BufferHubService(); | 
|  | ~BufferHubService() override; | 
|  |  | 
|  | pdx::Status<void> HandleMessage(pdx::Message& message) override; | 
|  | void HandleImpulse(pdx::Message& message) override; | 
|  |  | 
|  | void OnChannelClose(pdx::Message& message, | 
|  | const std::shared_ptr<pdx::Channel>& channel) override; | 
|  |  | 
|  | bool IsInitialized() const override; | 
|  | std::string DumpState(size_t max_length) override; | 
|  |  | 
|  | bool AddNamedBuffer(const std::string& name, | 
|  | const std::shared_ptr<ProducerChannel>& buffer); | 
|  | std::shared_ptr<ProducerChannel> GetNamedBuffer(const std::string& name); | 
|  | bool RemoveNamedBuffer(const ProducerChannel& buffer); | 
|  |  | 
|  | private: | 
|  | friend BASE; | 
|  |  | 
|  | std::unordered_map<std::string, std::shared_ptr<ProducerChannel>> | 
|  | named_buffers_; | 
|  |  | 
|  | pdx::Status<void> OnCreateBuffer(pdx::Message& message, uint32_t width, | 
|  | uint32_t height, uint32_t format, | 
|  | uint64_t usage, size_t meta_size_bytes); | 
|  | pdx::Status<void> OnCreatePersistentBuffer(pdx::Message& message, | 
|  | const std::string& name, | 
|  | int user_id, int group_id, | 
|  | uint32_t width, uint32_t height, | 
|  | uint32_t format, uint64_t usage, | 
|  | size_t meta_size_bytes); | 
|  | pdx::Status<void> OnGetPersistentBuffer(pdx::Message& message, | 
|  | const std::string& name); | 
|  | pdx::Status<QueueInfo> OnCreateProducerQueue( | 
|  | pdx::Message& message, const ProducerQueueConfig& producer_config, | 
|  | const UsagePolicy& usage_policy); | 
|  |  | 
|  | BufferHubService(const BufferHubService&) = delete; | 
|  | void operator=(const BufferHubService&) = delete; | 
|  | }; | 
|  |  | 
|  | }  // namespace dvr | 
|  | }  // namespace android | 
|  |  | 
|  | #endif  // ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_ |