| // Copyright 2019 The Fuchsia Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_BUFFER_COLLECTION_TOKEN_H_ | 
 | #define SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_BUFFER_COLLECTION_TOKEN_H_ | 
 |  | 
 | #include <fuchsia/sysmem/c/fidl.h> | 
 | #include <fuchsia/sysmem/llcpp/fidl.h> | 
 | #include <lib/fidl-async-2/fidl_server.h> | 
 | #include <lib/fidl-async-2/simple_binding.h> | 
 |  | 
 | #include "binding_handle.h" | 
 | #include "logging.h" | 
 | #include "logical_buffer_collection.h" | 
 |  | 
 | namespace sysmem_driver { | 
 |  | 
 | class BufferCollectionToken; | 
 |  | 
 | class BufferCollectionToken : public llcpp::fuchsia::sysmem::BufferCollectionToken::Interface, | 
 |                               public LoggingMixin, | 
 |                               public fbl::RefCounted<BufferCollectionToken> { | 
 |  public: | 
 |   ~BufferCollectionToken(); | 
 |  | 
 |   static BindingHandle<BufferCollectionToken> Create(Device* parent_device, | 
 |                                                      fbl::RefPtr<LogicalBufferCollection> parent, | 
 |                                                      uint32_t rights_attenuation_mask); | 
 |  | 
 |   void SetErrorHandler(fit::function<void(zx_status_t)> error_handler) { | 
 |     error_handler_ = std::move(error_handler); | 
 |   } | 
 |   void Bind(zx::channel channel); | 
 |  | 
 |   void Duplicate(uint32_t rights_attenuation_mask, zx::channel buffer_collection_token_request, | 
 |                  DuplicateCompleter::Sync& completer) override; | 
 |   void Sync(SyncCompleter::Sync&) override; | 
 |   void Close(CloseCompleter::Sync&) override; | 
 |   void SetName(uint32_t priority, fidl::StringView name, SetNameCompleter::Sync&) override; | 
 |   void SetDebugClientInfo(fidl::StringView, uint64_t id, | 
 |                           SetDebugClientInfoCompleter::Sync&) override; | 
 |   void SetDebugTimeoutLogDeadline(int64_t deadline, | 
 |                                   SetDebugTimeoutLogDeadlineCompleter::Sync&) override; | 
 |  | 
 |   void SetDebugClientInfo(std::string name, uint64_t id); | 
 |  | 
 |   LogicalBufferCollection* parent(); | 
 |   fbl::RefPtr<LogicalBufferCollection> parent_shared(); | 
 |  | 
 |   void SetServerKoid(zx_koid_t server_koid); | 
 |  | 
 |   zx_koid_t server_koid(); | 
 |  | 
 |   bool is_done(); | 
 |  | 
 |   bool was_unfound_token() const { return was_unfound_token_; } | 
 |  | 
 |   void SetBufferCollectionRequest(zx::channel buffer_collection_request); | 
 |  | 
 |   zx::channel TakeBufferCollectionRequest(); | 
 |  | 
 |   const std::string& debug_name() const { return debug_info_.name; } | 
 |   uint64_t debug_id() const { return debug_info_.id; } | 
 |  | 
 |   void CloseChannel(); | 
 |  | 
 |  private: | 
 |   friend class FidlServer; | 
 |   BufferCollectionToken(Device* parent_device, fbl::RefPtr<LogicalBufferCollection> parent, | 
 |                         uint32_t rights_attenuation_mask); | 
 |  | 
 |   void FailAsync(zx_status_t status, const char* format, ...); | 
 |  | 
 |   Device* parent_device_ = nullptr; | 
 |   fbl::RefPtr<LogicalBufferCollection> parent_; | 
 |   // 1 bit means the right is allowed.  0 bit means the right is attenuated. | 
 |   // | 
 |   // TODO(fxbug.dev/50578): Finish plumbing this. | 
 |   uint32_t rights_attenuation_mask_ = std::numeric_limits<uint32_t>::max(); | 
 |   fit::function<void(zx_status_t)> error_handler_; | 
 |  | 
 |   zx_koid_t server_koid_ = ZX_KOID_INVALID; | 
 |  | 
 |   // Becomes true on the first Close() or BindSharedCollection().  This being | 
 |   // true means a channel close is not fatal to the LogicalBufferCollection. | 
 |   // However, if the client sends a redundant Close(), that is fatal to the | 
 |   // BufferCollectionToken and fatal to the LogicalBufferCollection. | 
 |   bool is_done_ = false; | 
 |  | 
 |   bool was_unfound_token_ = false; | 
 |  | 
 |   std::optional<fidl::ServerBindingRef<llcpp::fuchsia::sysmem::BufferCollectionToken>> | 
 |       server_binding_; | 
 |  | 
 |   // This is set up to once during | 
 |   // LogicalBufferCollection::BindSharedCollection(), and essentially curries | 
 |   // the buffer_collection_request past the processing of any remaining | 
 |   // inbound messages on the BufferCollectionToken before starting to serve | 
 |   // the BufferCollection that the token was exchanged for.  This way, inbound | 
 |   // Duplicate() messages in the BufferCollectionToken are seen before any | 
 |   // BufferCollection::SetConstraints() (which might otherwise try to allocate | 
 |   // buffers too soon before all tokens are gone). | 
 |   zx::channel buffer_collection_request_; | 
 |  | 
 |   LogicalBufferCollection::ClientInfo debug_info_; | 
 |   inspect::Node node_; | 
 |   inspect::UintProperty debug_id_property_; | 
 |   inspect::StringProperty debug_name_property_; | 
 | }; | 
 |  | 
 | }  // namespace sysmem_driver | 
 |  | 
 | #endif  // SRC_DEVICES_SYSMEM_DRIVERS_SYSMEM_BUFFER_COLLECTION_TOKEN_H_ |