// 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.

#include "buffer_collection.h"

#include <fuchsia/sysmem/c/fidl.h>
#include <lib/fidl-async-2/fidl_struct.h>
#include <lib/fidl-utils/bind.h>
#include <lib/sysmem-version/sysmem-version.h>
#include <zircon/compiler.h>
#include <zircon/errors.h>

#include <atomic>

#include <ddk/trace/event.h>

#include "fuchsia/sysmem/c/fidl.h"
#include "logical_buffer_collection.h"
#include "macros.h"
#include "utils.h"

namespace sysmem_driver {

namespace {

using BufferCollectionInfo_v1 = FidlStruct<fuchsia_sysmem_BufferCollectionInfo_2,
                                           llcpp::fuchsia::sysmem::BufferCollectionInfo_2>;

constexpr uint32_t kConcurrencyCap = 64;

// For max client vmo rights, we specify the RIGHT bits individually to avoid
// picking up any newly-added rights unintentionally.  This is based on
// ZX_DEFAULT_VMO_RIGHTS, but with a few rights removed.
const uint32_t kMaxClientVmoRights =
    // ZX_RIGHTS_BASIC, except ZX_RIGHT_INSPECT (at least for now).
    ZX_RIGHT_TRANSFER | ZX_RIGHT_DUPLICATE | ZX_RIGHT_WAIT |
    // ZX_RIGHTS_IO:
    ZX_RIGHT_READ | ZX_RIGHT_WRITE |
    // ZX_RIGHTS_PROPERTY allows a participant to set ZX_PROP_NAME for easier
    // memory metrics.  Nothing prevents participants from figting over the
    // name, though the kernel should make each set/get atomic with respect to
    // other set/get.  This relies on ZX_RIGHTS_PROPERTY not implying anything
    // that could be used as an attack vector between processes sharing a VMO.
    ZX_RIGHTS_PROPERTY |
    // We intentionally omit ZX_RIGHT_EXECUTE (indefinitely) and ZX_RIGHT_SIGNAL
    // (at least for now).
    //
    // Remaining bits of ZX_DEFAULT_VMO_RIGHTS (as of this writing):
    ZX_RIGHT_MAP;

}  // namespace

const fuchsia_sysmem_BufferCollection_ops_t BufferCollection::kOps = {
    fidl::Binder<BufferCollection>::BindMember<&BufferCollection::SetEventSink>,
    fidl::Binder<BufferCollection>::BindMember<&BufferCollection::Sync>,
    fidl::Binder<BufferCollection>::BindMember<&BufferCollection::SetConstraints>,
    fidl::Binder<BufferCollection>::BindMember<&BufferCollection::WaitForBuffersAllocated>,
    fidl::Binder<BufferCollection>::BindMember<&BufferCollection::CheckBuffersAllocated>,
    fidl::Binder<BufferCollection>::BindMember<&BufferCollection::CloseSingleBuffer>,
    fidl::Binder<BufferCollection>::BindMember<&BufferCollection::AllocateSingleBuffer>,
    fidl::Binder<BufferCollection>::BindMember<&BufferCollection::WaitForSingleBufferAllocated>,
    fidl::Binder<BufferCollection>::BindMember<&BufferCollection::CheckSingleBufferAllocated>,
    fidl::Binder<BufferCollection>::BindMember<&BufferCollection::Close>,
    fidl::Binder<BufferCollection>::BindMember<&BufferCollection::SetName>,
    fidl::Binder<BufferCollection>::BindMember<&BufferCollection::SetDebugClientInfo>,
    fidl::Binder<BufferCollection>::BindMember<&BufferCollection::SetConstraintsAuxBuffers>,
    fidl::Binder<BufferCollection>::BindMember<&BufferCollection::GetAuxBuffers>,
};

BufferCollection::~BufferCollection() {
  TRACE_DURATION("gfx", "BufferCollection::~BufferCollection", "this", this, "parent",
                 parent_.get());
  // Close() the SimpleBinding<> before deleting the list of pending Txn(s),
  // so that ~Txn doesn't complain about being deleted without being
  // completed.
  //
  // Don't run the error handler; if any error handler remains it'll just get
  // deleted here.
  (void)binding_.Close();
}

zx_status_t BufferCollection::SetEventSink(zx_handle_t buffer_collection_events_client_param) {
  zx::channel buffer_collection_events_client(buffer_collection_events_client_param);
  if (is_done_) {
    FailAsync(ZX_ERR_BAD_STATE, "BufferCollectionToken::SetEventSink() when already is_done_");
    // We're failing async - no need to try to fail sync.
    return ZX_OK;
  }
  if (!buffer_collection_events_client) {
    zx_status_t status = ZX_ERR_INVALID_ARGS;
    FailAsync(status,
              "BufferCollection::SetEventSink() must be called "
              "with a non-zero handle.");
    return status;
  }
  if (is_set_constraints_seen_) {
    zx_status_t status = ZX_ERR_INVALID_ARGS;
    // It's not required to use SetEventSink(), but if it's used, it must be
    // before SetConstraints().
    FailAsync(status,
              "BufferCollection::SetEventSink() (if any) must be "
              "before SetConstraints().");
    return status;
  }
  if (events_) {
    zx_status_t status = ZX_ERR_INVALID_ARGS;
    FailAsync(status, "BufferCollection::SetEventSink() may only be called at most once.");
    return status;
  }
  events_ = std::move(buffer_collection_events_client);
  // We don't create BufferCollection until after processing all inbound
  // messages that were queued toward the server on the token channel of the
  // token that was used to create this BufferCollection, so we can send this
  // event now, as all the Duplicate() inbound from that token are done being
  // processed before here.
  fuchsia_sysmem_BufferCollectionEventsOnDuplicatedTokensKnownByServer(events_.get());
  return ZX_OK;
}

zx_status_t BufferCollection::Sync(fidl_txn_t* txn) {
  BindingType::Txn::RecognizeTxn(txn);
  return fuchsia_sysmem_BufferCollectionSync_reply(txn);
}

zx_status_t BufferCollection::SetConstraintsAuxBuffers(
    const fuchsia_sysmem_BufferCollectionConstraintsAuxBuffers* constraints_param) {
  ZX_DEBUG_ASSERT(constraints_param);

  // Copy data and own handles.
  static_assert(sizeof(llcpp::fuchsia::sysmem::BufferCollectionConstraintsAuxBuffers) ==
                sizeof(fuchsia_sysmem_BufferCollectionConstraintsAuxBuffers));
  llcpp::fuchsia::sysmem::BufferCollectionConstraintsAuxBuffers local_constraints;
  memcpy(&local_constraints, constraints_param, sizeof(local_constraints));

  if (is_set_constraints_aux_buffers_seen_) {
    FailAsync(ZX_ERR_NOT_SUPPORTED, "SetConstraintsAuxBuffers() can be called only once.");
    return ZX_ERR_NOT_SUPPORTED;
  }
  is_set_constraints_aux_buffers_seen_ = true;
  if (is_done_) {
    FailAsync(ZX_ERR_BAD_STATE,
              "BufferCollectionToken::SetConstraintsAuxBuffers() when already is_done_");
    // We're failing async - no need to try to fail sync.
    return ZX_OK;
  }
  if (is_set_constraints_seen_) {
    FailAsync(ZX_ERR_NOT_SUPPORTED,
              "SetConstraintsAuxBuffers() after SetConstraints() causes failure.");
    return ZX_ERR_NOT_SUPPORTED;
  }
  ZX_DEBUG_ASSERT(!constraints_aux_buffers_);
  constraints_aux_buffers_.emplace(std::move(local_constraints));
  // LogicalBufferCollection doesn't care about "clear aux buffers" constraints until the last
  // SetConstraints(), so done for now.
  return ZX_OK;
}

zx_status_t BufferCollection::SetConstraints(
    bool has_constraints, const fuchsia_sysmem_BufferCollectionConstraints* constraints_param) {
  TRACE_DURATION("gfx", "BufferCollection::SetConstraints", "this", this, "parent", parent_.get());
  // Regardless of has_constraints or not, we need to unconditionally take
  // ownership of any handles in constraints_param.  Not that there are
  // necessarily any handles in here currently, but to avoid being fragile re.
  // any handles potentially added later.
  ZX_DEBUG_ASSERT(constraints_param);

  // Copy data and own handles.
  static_assert(sizeof(llcpp::fuchsia::sysmem::BufferCollectionConstraints) ==
                sizeof(fuchsia_sysmem_BufferCollectionConstraints));
  std::optional<llcpp::fuchsia::sysmem::BufferCollectionConstraints> local_constraints;
  local_constraints.emplace();
  memcpy(&local_constraints.value(), constraints_param, sizeof(local_constraints.value()));

  if (is_set_constraints_seen_) {
    FailAsync(ZX_ERR_NOT_SUPPORTED, "2nd SetConstraints() causes failure.");
    return ZX_ERR_NOT_SUPPORTED;
  }
  is_set_constraints_seen_ = true;
  if (is_done_) {
    FailAsync(ZX_ERR_BAD_STATE, "BufferCollectionToken::SetConstraints() when already is_done_");
    // We're failing async - no need to try to fail sync.
    return ZX_OK;
  }
  if (!has_constraints) {
    // Not needed.
    local_constraints.reset();
    if (is_set_constraints_aux_buffers_seen_) {
      // No constraints are fine, just not aux buffers constraints without main constraints, because
      // I can't think of any reason why we'd need to support aux buffers constraints without main
      // constraints, so disallow at least for now.
      FailAsync(ZX_ERR_NOT_SUPPORTED, "SetConstraintsAuxBuffers() && !has_constraints");
      return ZX_ERR_NOT_SUPPORTED;
    }
  }

  ZX_DEBUG_ASSERT(!constraints_);
  // enforced above
  ZX_DEBUG_ASSERT(!constraints_aux_buffers_ || local_constraints);
  ZX_DEBUG_ASSERT(has_constraints == !!local_constraints);
  {  // scope result
    auto result = sysmem::V2CopyFromV1BufferCollectionConstraints(
        &allocator_, local_constraints ? &local_constraints.value() : nullptr,
        constraints_aux_buffers_ ? &constraints_aux_buffers_.value() : nullptr);
    if (!result.is_ok()) {
      parent_->LogClientError(&debug_info_, "V2CopyFromV1BufferCollectionConstraints() failed");
      return ZX_ERR_INVALID_ARGS;
    }
    ZX_DEBUG_ASSERT(!result.value().IsEmpty() || !local_constraints);
    constraints_.emplace(result.take_value());
  }  // ~result
  // No longer needed.
  constraints_aux_buffers_.reset();

  // Stash BufferUsage also, for benefit of GetUsageBasedRightsAttenuation() depsite
  // TakeConstraints().
  {  // scope buffer_usage
    llcpp::fuchsia::sysmem::BufferUsage empty_buffer_usage{};
    llcpp::fuchsia::sysmem::BufferUsage* source_buffer_usage = &empty_buffer_usage;
    if (local_constraints) {
      source_buffer_usage = &local_constraints.value().usage;
    }
    auto result = sysmem::V2CopyFromV1BufferUsage(&allocator_, *source_buffer_usage);
    if (!result.is_ok()) {
      parent_->LogClientError(&debug_info_, "V2CopyFromV1BufferUsage failed");
      // Not expected given current impl of sysmem-version.
      return ZX_ERR_INTERNAL;
    }
    usage_.emplace(result.take_value().build());
  }  // ~buffer_usage

  // LogicalBufferCollection will ask for constraints when it needs them,
  // possibly during this call if this is the last participant to report
  // having initial constraints.
  //
  // The LogicalBufferCollection cares if this BufferCollection view has null
  // constraints, but only later when it asks for the specific constraints.
  parent()->OnSetConstraints();
  // |this| may be gone at this point, if the allocation failed.  Regardless,
  // SetConstraints() worked, so ZX_OK.
  return ZX_OK;
}

zx_status_t BufferCollection::WaitForBuffersAllocated(fidl_txn_t* txn_param) {
  TRACE_DURATION("gfx", "BufferCollection::WaitForBuffersAllocated", "this", this, "parent",
                 parent_.get());
  BindingType::Txn::RecognizeTxn(txn_param);
  if (is_done_) {
    FailAsync(ZX_ERR_BAD_STATE,
              "BufferCollectionToken::WaitForBuffersAllocated() when already is_done_");
    // We're failing async - no need to fail sync.
    return ZX_OK;
  }
  // In general we're handling this async, so take ownership of the txn.
  std::unique_ptr<BindingType::Txn> txn = BindingType::Txn::TakeTxn(txn_param);
  trace_async_id_t current_event_id = TRACE_NONCE();
  TRACE_ASYNC_BEGIN("gfx", "BufferCollection::WaitForBuffersAllocated async", current_event_id,
                    "this", this, "parent", parent_.get());
  pending_wait_for_buffers_allocated_.emplace_back(
      std::make_pair(current_event_id, std::move(txn)));
  // The allocation is a one-shot (once true, remains true) and may already be
  // done, in which case this immediately completes txn.
  MaybeCompleteWaitForBuffersAllocated();
  return ZX_OK;
}

zx_status_t BufferCollection::CheckBuffersAllocated(fidl_txn_t* txn) {
  BindingType::Txn::RecognizeTxn(txn);
  if (is_done_) {
    FailAsync(ZX_ERR_BAD_STATE,
              "BufferCollectionToken::CheckBuffersAllocated() when "
              "already is_done_");
    // We're failing async - no need to try to fail sync.
    return ZX_OK;
  }
  LogicalBufferCollection::AllocationResult allocation_result = parent()->allocation_result();
  if (allocation_result.status == ZX_OK && !allocation_result.buffer_collection_info) {
    return fuchsia_sysmem_BufferCollectionCheckBuffersAllocated_reply(txn, ZX_ERR_UNAVAILABLE);
  }
  // Buffer collection has either been allocated or failed.
  return fuchsia_sysmem_BufferCollectionCheckBuffersAllocated_reply(txn, allocation_result.status);
}

zx_status_t BufferCollection::GetAuxBuffers(fidl_txn_t* txn_param) {
  BindingType::Txn::RecognizeTxn(txn_param);
  LogicalBufferCollection::AllocationResult allocation_result = parent()->allocation_result();
  if (allocation_result.status == ZX_OK && !allocation_result.buffer_collection_info) {
    FailAsync(ZX_ERR_BAD_STATE, "GetAuxBuffers() called before allocation complete.",
              ZX_ERR_BAD_STATE);
    // We're failing async - no need to fail sync.
    return ZX_OK;
  }
  if (allocation_result.status != ZX_OK) {
    FailAsync(ZX_ERR_BAD_STATE, "GetAuxBuffers() called after allocation failure.",
              ZX_ERR_BAD_STATE);
    // We're failing async - no need to fail sync.
    return ZX_OK;
  }
  BufferCollection::V1CBufferCollectionInfo v1_c(
      BufferCollection::V1CBufferCollectionInfo::Default);
  ZX_DEBUG_ASSERT(allocation_result.buffer_collection_info);
  auto v1_c_result = CloneAuxBuffersResultForSendingV1(*allocation_result.buffer_collection_info);
  if (!v1_c_result.is_ok()) {
    // FailAsync() already called.
    //
    // We're failing async - no need to fail sync.
    return ZX_OK;
  }
  v1_c = v1_c_result.take_value();
  // Ownership of handles in to_send are transferred to _reply().
  zx_status_t reply_status = fuchsia_sysmem_BufferCollectionGetAuxBuffers_reply(
      txn_param, allocation_result.status, v1_c.release());
  if (reply_status != ZX_OK) {
    FailAsync(reply_status,
              "fuchsia_sysmem_BufferCollectionGetAuxBuffers_reply failed - status: %d",
              reply_status);
    // We're failing async - no need to fail sync.
    return ZX_OK;
  }
  return ZX_OK;
}

zx_status_t BufferCollection::CloseSingleBuffer(uint64_t buffer_index) {
  if (is_done_) {
    FailAsync(ZX_ERR_BAD_STATE, "BufferCollectionToken::CloseSingleBuffer() when already is_done_");
    // We're failing async - no need to try to fail sync.
    return ZX_OK;
  }
  // FailAsync() instead of returning a failure, mainly because FailAsync()
  // prints a message that's more obvious than the generic _dispatch() failure
  // would.
  FailAsync(ZX_ERR_NOT_SUPPORTED, "CloseSingleBuffer() not yet implemented");
  return ZX_OK;
}

zx_status_t BufferCollection::AllocateSingleBuffer(uint64_t buffer_index) {
  if (is_done_) {
    FailAsync(ZX_ERR_BAD_STATE,
              "BufferCollectionToken::AllocateSingleBuffer() when already "
              "is_done_");
    // We're failing async - no need to try to fail sync.
    return ZX_OK;
  }
  FailAsync(ZX_ERR_NOT_SUPPORTED, "AllocateSingleBuffer() not yet implemented");
  return ZX_OK;
}

zx_status_t BufferCollection::WaitForSingleBufferAllocated(uint64_t buffer_index, fidl_txn_t* txn) {
  BindingType::Txn::RecognizeTxn(txn);
  if (is_done_) {
    FailAsync(ZX_ERR_BAD_STATE,
              "BufferCollectionToken::WaitForSingleBufferAllocated() when "
              "already is_done_");
    // We're failing async - no need to try to fail sync.
    return ZX_OK;
  }
  FailAsync(ZX_ERR_NOT_SUPPORTED, "WaitForSingleBufferAllocated() not yet implemented");
  return ZX_OK;
}

zx_status_t BufferCollection::CheckSingleBufferAllocated(uint64_t buffer_index) {
  if (is_done_) {
    FailAsync(ZX_ERR_BAD_STATE,
              "BufferCollectionToken::CheckSingleBufferAllocated() when "
              "already is_done_");
    // We're failing async - no need to try to fail sync.
    return ZX_OK;
  }
  FailAsync(ZX_ERR_NOT_SUPPORTED, "CheckSingleBufferAllocated() not yet implemented");
  return ZX_OK;
}

zx_status_t BufferCollection::Close() {
  if (is_done_) {
    FailAsync(ZX_ERR_BAD_STATE, "BufferCollection::Close() when already closed.");
    return ZX_OK;
  }
  // We still want to enforce that the client doesn't send any other messages
  // between Close() and closing the channel, so we just set is_done_ here and
  // do a FailAsync() if is_done_ is seen to be set while handling any other
  // message.
  is_done_ = true;
  return ZX_OK;
}

zx_status_t BufferCollection::SetName(uint32_t priority, const char* name_data, size_t name_size) {
  parent_->SetName(priority, std::string(name_data, name_size));
  return ZX_OK;
}

zx_status_t BufferCollection::SetDebugClientInfo(const char* name_data, size_t name_size,
                                                 uint64_t id) {
  debug_info_.name = std::string(name_data, name_size);
  debug_info_.id = id;
  debug_id_property_ = node_.CreateUint("debug_id", debug_info_.id);
  debug_name_property_ = node_.CreateString("debug_name", debug_info_.name);
  return ZX_OK;
}

void BufferCollection::FailAsync(zx_status_t status, const char* format, ...) {
  va_list args;
  va_start(args, format);
  parent_->VLogClientError(&debug_info_, format, args);

  va_end(args);
  FidlServer::FailAsync(status, "");
}

fit::result<llcpp::fuchsia::sysmem2::BufferCollectionInfo::Builder>
BufferCollection::CloneResultForSendingV2(
    const llcpp::fuchsia::sysmem2::BufferCollectionInfo& buffer_collection_info) {
  auto clone_result = sysmem::V2CloneBufferCollectionInfo(
      &allocator_, buffer_collection_info, GetClientVmoRights(), GetClientAuxVmoRights());
  if (!clone_result.is_ok()) {
    FailAsync(clone_result.error(),
              "CloneResultForSendingV1() V2CloneBufferCollectionInfo() failed - status: %d",
              clone_result.error());
    return fit::error();
  }
  auto v2_b = clone_result.take_value();
  if (!IsAnyUsage(usage_.value())) {
    // No VMO handles should be sent to the client in this case.
    if (v2_b.has_buffers()) {
      for (auto& vmo_buffer : v2_b.buffers()) {
        if (vmo_buffer.has_vmo()) {
          vmo_buffer.vmo().reset();
        }
        if (vmo_buffer.has_aux_vmo()) {
          vmo_buffer.aux_vmo().reset();
        }
      }
    }
  }
  return fit::ok(std::move(v2_b));
}

fit::result<BufferCollection::V1CBufferCollectionInfo> BufferCollection::CloneResultForSendingV1(
    const llcpp::fuchsia::sysmem2::BufferCollectionInfo& buffer_collection_info) {
  auto v2_builder_result = CloneResultForSendingV2(buffer_collection_info);
  if (!v2_builder_result.is_ok()) {
    // FailAsync() already called.
    return fit::error();
  }
  auto v1_result = sysmem::V1MoveFromV2BufferCollectionInfo(v2_builder_result.take_value().build());
  if (!v1_result.is_ok()) {
    FailAsync(ZX_ERR_INVALID_ARGS,
              "CloneResultForSendingV1() V1MoveFromV2BufferCollectionInfo() failed");
    return fit::error();
  }
  V1CBufferCollectionInfo v1_c(V1CBufferCollectionInfo::Default);
  // struct move
  v1_c.BorrowAsLlcpp() = v1_result.take_value();
  return fit::ok(std::move(v1_c));
}

fit::result<BufferCollection::V1CBufferCollectionInfo>
BufferCollection::CloneAuxBuffersResultForSendingV1(
    const llcpp::fuchsia::sysmem2::BufferCollectionInfo& buffer_collection_info) {
  auto v2_builder_result = CloneResultForSendingV2(buffer_collection_info);
  if (!v2_builder_result.is_ok()) {
    // FailAsync() already called.
    return fit::error();
  }
  auto v1_result =
      sysmem::V1AuxBuffersMoveFromV2BufferCollectionInfo(v2_builder_result.take_value().build());
  if (!v1_result.is_ok()) {
    FailAsync(ZX_ERR_INVALID_ARGS,
              "CloneResultForSendingV1() V1MoveFromV2BufferCollectionInfo() failed");
    return fit::error();
  }
  V1CBufferCollectionInfo v1_c(V1CBufferCollectionInfo::Default);
  // struct move
  v1_c.BorrowAsLlcpp() = v1_result.take_value();
  return fit::ok(std::move(v1_c));
}

void BufferCollection::OnBuffersAllocated() {
  // Any that are pending are completed by this call or something called
  // FailAsync().  It's fine for this method to ignore the fact that
  // FailAsync() may have already been called.  That's essentially the main
  // reason we have FailAsync() instead of Fail().
  MaybeCompleteWaitForBuffersAllocated();

  if (!events_) {
    return;
  }

  BufferCollection::V1CBufferCollectionInfo v1_c(
      BufferCollection::V1CBufferCollectionInfo::Default);
  if (parent()->allocation_result().status == ZX_OK) {
    ZX_DEBUG_ASSERT(parent()->allocation_result().buffer_collection_info);
    auto v1_c_result =
        CloneResultForSendingV1(*parent()->allocation_result().buffer_collection_info);
    if (!v1_c_result.is_ok()) {
      // FailAsync() already called.
      return;
    }
    v1_c = v1_c_result.take_value();
  }

  // Ownership of all handles in to_send is transferred to this function.
  fuchsia_sysmem_BufferCollectionEventsOnBuffersAllocated(
      events_.get(), parent()->allocation_result().status, v1_c.release());
}

bool BufferCollection::has_constraints() { return !!constraints_; }

const llcpp::fuchsia::sysmem2::BufferCollectionConstraints::Builder&
BufferCollection::constraints() {
  ZX_DEBUG_ASSERT(has_constraints());
  return constraints_.value();
}

llcpp::fuchsia::sysmem2::BufferCollectionConstraints::Builder BufferCollection::TakeConstraints() {
  ZX_DEBUG_ASSERT(has_constraints());
  llcpp::fuchsia::sysmem2::BufferCollectionConstraints::Builder result =
      std::move(constraints_.value());
  constraints_.reset();
  return result;
}

LogicalBufferCollection* BufferCollection::parent() { return parent_.get(); }

fbl::RefPtr<LogicalBufferCollection> BufferCollection::parent_shared() { return parent_; }

bool BufferCollection::is_done() { return is_done_; }

BufferCollection::BufferCollection(fbl::RefPtr<LogicalBufferCollection> parent)
    : FidlServer(parent->parent_device()->dispatcher(), "BufferCollection", kConcurrencyCap),
      parent_(parent),
      allocator_(parent->fidl_allocator()) {
  TRACE_DURATION("gfx", "BufferCollection::BufferCollection", "this", this, "parent",
                 parent_.get());
  ZX_DEBUG_ASSERT(parent_);
  node_ = parent_->node().CreateChild(CreateUniqueName("collection-"));
}

// This method is only meant to be called from GetClientVmoRights().
uint32_t BufferCollection::GetUsageBasedRightsAttenuation() {
  // This method won't be called for participants without any buffer data "usage".
  ZX_DEBUG_ASSERT(usage_);

  // We assume that read and map are both needed by all participants with any "usage".  Only
  // ZX_RIGHT_WRITE is controlled by usage.

  // It's not this method's job to attenuate down to kMaxClientVmoRights, so
  // let's not pretend like it is.
  uint32_t result = std::numeric_limits<uint32_t>::max();
  if (!IsWriteUsage(usage_.value())) {
    result &= ~ZX_RIGHT_WRITE;
  }

  return result;
}

uint32_t BufferCollection::GetClientVmoRights() {
  return
      // max possible rights for a client to have
      kMaxClientVmoRights &
      // attenuate write if client doesn't need write
      GetUsageBasedRightsAttenuation() &
      // attenuate according to BufferCollectionToken.Duplicate() rights
      // parameter so that initiator and participant can distribute the token
      // and remove any unnecessary/unintended rights along the way.
      client_rights_attenuation_mask_;
}

uint32_t BufferCollection::GetClientAuxVmoRights() {
  // At least for now.
  return GetClientVmoRights();
}

void BufferCollection::MaybeCompleteWaitForBuffersAllocated() {
  LogicalBufferCollection::AllocationResult allocation_result = parent()->allocation_result();
  if (allocation_result.status == ZX_OK && !allocation_result.buffer_collection_info) {
    // Everything is ok so far, but allocation isn't done yet.
    return;
  }
  while (!pending_wait_for_buffers_allocated_.empty()) {
    auto [async_id, txn] = std::move(pending_wait_for_buffers_allocated_.front());
    pending_wait_for_buffers_allocated_.pop_front();

    BufferCollection::V1CBufferCollectionInfo v1_c(
        BufferCollection::V1CBufferCollectionInfo::Default);
    if (allocation_result.status == ZX_OK) {
      ZX_DEBUG_ASSERT(allocation_result.buffer_collection_info);
      auto v1_c_result = CloneResultForSendingV1(*allocation_result.buffer_collection_info);
      if (!v1_c_result.is_ok()) {
        // FailAsync() already called.
        return;
      }
      v1_c = v1_c_result.take_value();
    }
    TRACE_ASYNC_END("gfx", "BufferCollection::WaitForBuffersAllocated async", async_id, "this",
                    this, "parent", parent_.get());
    // Ownership of handles in to_send are transferred to _reply().
    zx_status_t reply_status = fuchsia_sysmem_BufferCollectionWaitForBuffersAllocated_reply(
        &txn->raw_txn(), allocation_result.status, v1_c.release());
    if (reply_status != ZX_OK) {
      FailAsync(reply_status,
                "fuchsia_sysmem_BufferCollectionWaitForBuffersAllocated_"
                "reply failed - status: %d",
                reply_status);
      return;
    }
    // ~txn
  }
}

}  // namespace sysmem_driver
