// Copyright 2017 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 "src/media/audio/audio_core/audio_driver.h"

#include <audio-proto-utils/format-utils.h>

#include <cstdio>

#include "lib/fidl/cpp/clone.h"
#include "src/lib/fxl/logging.h"
#include "src/media/audio/audio_core/driver_utils.h"

namespace media::audio {

static constexpr zx_txid_t TXID = 1;
static constexpr zx_duration_t kDefaultShortCmdTimeout = ZX_MSEC(250);
static constexpr zx_duration_t kDefaultLongCmdTimeout = ZX_SEC(3);

AudioDriver::AudioDriver(AudioDevice* owner) : owner_(owner) {
  FXL_DCHECK(owner_ != nullptr);
  stream_channel_ = ::dispatcher::Channel::Create();
  rb_channel_ = ::dispatcher::Channel::Create();
  cmd_timeout_ = ::dispatcher::Timer::Create();
}

zx_status_t AudioDriver::Init(zx::channel stream_channel) {
  FXL_DCHECK(state_ == State::Uninitialized);

  if ((stream_channel_ == nullptr) || (rb_channel_ == nullptr) ||
      (cmd_timeout_ == nullptr)) {
    return ZX_ERR_NO_RESOURCES;
  }

  // Fetch the KOID of our stream channel.  We will end up using this unique ID
  // as our device's device token.
  zx_status_t res;
  zx_info_handle_basic_t sc_info;
  res = stream_channel.get_info(ZX_INFO_HANDLE_BASIC, &sc_info, sizeof(sc_info),
                                nullptr, nullptr);
  if (res != ZX_OK) {
    FXL_LOG(ERROR) << "Failed to to fetch stream channel KOID (res " << res
                   << ")";
    return res;
  }
  stream_channel_koid_ = sc_info.koid;

  // Activate the stream channel.
  ::dispatcher::Channel::ProcessHandler process_handler(
      [this](::dispatcher::Channel* channel) -> zx_status_t {
        OBTAIN_EXECUTION_DOMAIN_TOKEN(token, owner_->mix_domain_);
        FXL_DCHECK(stream_channel_.get() == channel);
        return ProcessStreamChannelMessage();
      });

  ::dispatcher::Channel::ChannelClosedHandler channel_closed_handler(
      [this](const ::dispatcher::Channel* channel) {
        OBTAIN_EXECUTION_DOMAIN_TOKEN(token, owner_->mix_domain_);
        FXL_DCHECK(stream_channel_.get() == channel);
        ShutdownSelf("Stream channel closed unexpectedly", ZX_ERR_PEER_CLOSED);
      });

  res = stream_channel_->Activate(
      std::move(stream_channel), owner_->mix_domain_,
      std::move(process_handler), std::move(channel_closed_handler));
  if (res != ZX_OK) {
    FXL_LOG(ERROR) << "Failed to activate stream channel for AudioDriver!  "
                   << "(res " << res << ")";
    return res;
  }

  // Activate the command timeout timer.
  ::dispatcher::Timer::ProcessHandler cmd_timeout_handler(
      [this](::dispatcher::Timer* timer) -> zx_status_t {
        OBTAIN_EXECUTION_DOMAIN_TOKEN(token, owner_->mix_domain_);
        FXL_DCHECK(cmd_timeout_.get() == timer);
        ShutdownSelf("Unexpected command timeout", ZX_ERR_TIMED_OUT);
        return ZX_OK;
      });

  res = cmd_timeout_->Activate(owner_->mix_domain_,
                               std::move(cmd_timeout_handler));
  if (res != ZX_OK) {
    FXL_LOG(ERROR)
        << "Failed to activate command timeout timer for AudioDriver!  "
        << "(res " << res << ")";
    return res;
  }

  // We are now initialized, but we don't know any of our fundamental driver
  // level info.  Things like...
  //
  // 1) This device's persistent unique ID.
  // 2) The list of formats supported by this device.
  // 3) The user visible strings for this device (manufacturer, product, etc...)
  state_ = State::MissingDriverInfo;
  return ZX_OK;
}

void AudioDriver::Cleanup() {
  fbl::RefPtr<DriverRingBuffer> ring_buffer;
  {
    std::lock_guard<std::mutex> lock(ring_buffer_state_lock_);
    ring_buffer = std::move(ring_buffer_);
    clock_mono_to_ring_pos_bytes_ = TimelineFunction();
    ring_buffer_state_gen_.Next();
  }
  ring_buffer.reset();

  stream_channel_->Deactivate();
  rb_channel_->Deactivate();
  cmd_timeout_->Deactivate();
}

void AudioDriver::SnapshotRingBuffer(RingBufferSnapshot* snapshot) const {
  FXL_DCHECK(snapshot);
  std::lock_guard<std::mutex> lock(ring_buffer_state_lock_);

  snapshot->ring_buffer = ring_buffer_;
  snapshot->clock_mono_to_ring_pos_bytes = clock_mono_to_ring_pos_bytes_;
  snapshot->position_to_end_fence_frames =
      owner_->is_input() ? fifo_depth_frames() : 0;
  snapshot->end_fence_to_start_fence_frames = end_fence_to_start_fence_frames_;
  snapshot->gen_id = ring_buffer_state_gen_.get();
}

fuchsia::media::AudioStreamTypePtr AudioDriver::GetSourceFormat() const {
  std::lock_guard<std::mutex> lock(configured_format_lock_);

  if (!configured_format_)
    return nullptr;

  fuchsia::media::AudioStreamTypePtr result;
  fidl::Clone(configured_format_, &result);
  return result;
}

zx_status_t AudioDriver::GetDriverInfo() {
  // TODO(johngro) : Figure out a better way to assert this!
  OBTAIN_EXECUTION_DOMAIN_TOKEN(token, owner_->mix_domain_);

  // We have to be operational in order to fetch supported formats.
  if (!operational()) {
    FXL_LOG(ERROR)
        << "Cannot fetch supported formats while non-operational (state = "
        << static_cast<uint32_t>(state_) << ")";
    return ZX_ERR_BAD_STATE;
  }

  // If we are already in the process of fetching our initial driver info, just
  // get out now.  We will inform our owner when the process completes.
  if (fetching_driver_info()) {
    return ZX_OK;
  }

  // Send the commands to do the following.
  //
  // 1) Fetch our persistent unique ID.
  // 2) Fetch our manufacturer string.
  // 3) Fetch our product string.
  // 4) Fetch our current gain state/caps
  // 5) Fetch our supported format list.

  // Step #1, fetch unique IDs.
  {
    audio_stream_cmd_get_formats_req_t req;
    req.hdr.cmd = AUDIO_STREAM_CMD_GET_UNIQUE_ID;
    req.hdr.transaction_id = TXID;

    zx_status_t res = stream_channel_->Write(&req, sizeof(req));
    if (res != ZX_OK) {
      ShutdownSelf("Failed to request unique ID.", res);
      return res;
    }
  }

  // Steps #2-3, fetch strings.
  static const audio_stream_string_id_t kStringsToFetch[] = {
      AUDIO_STREAM_STR_ID_MANUFACTURER,
      AUDIO_STREAM_STR_ID_PRODUCT,
  };
  for (const auto string_id : kStringsToFetch) {
    audio_stream_cmd_get_string_req_t req;
    req.hdr.cmd = AUDIO_STREAM_CMD_GET_STRING;
    req.hdr.transaction_id = TXID;
    req.id = string_id;

    zx_status_t res = stream_channel_->Write(&req, sizeof(req));
    if (res != ZX_OK) {
      ShutdownSelf("Failed to request string.", res);
      return res;
    }
  }

  // Step #4.  Fetch our current gain state.
  {
    audio_stream_cmd_get_gain_req_t req;
    req.hdr.cmd = AUDIO_STREAM_CMD_GET_GAIN;
    req.hdr.transaction_id = TXID;

    zx_status_t res = stream_channel_->Write(&req, sizeof(req));
    if (res != ZX_OK) {
      ShutdownSelf("Failed to request gain state.", res);
      return res;
    }
  }

  // Step #5.  Fetch our list of supported formats.
  {
    FXL_DCHECK(format_ranges_.empty());

    // Actually send the request to the driver.
    audio_stream_cmd_get_formats_req_t req;
    req.hdr.cmd = AUDIO_STREAM_CMD_GET_FORMATS;
    req.hdr.transaction_id = TXID;

    zx_status_t res = stream_channel_->Write(&req, sizeof(req));
    if (res != ZX_OK) {
      ShutdownSelf("Failed to request supported format list.", res);
      return res;
    }
  }

  // Setup our command timeout.
  fetch_driver_info_timeout_ = zx_deadline_after(kDefaultShortCmdTimeout);
  SetupCommandTimeout();
  return ZX_OK;
}

zx_status_t AudioDriver::Configure(uint32_t frames_per_second,
                                   uint32_t channels,
                                   fuchsia::media::AudioSampleFormat fmt,
                                   zx_duration_t min_ring_buffer_duration) {
  // TODO(johngro) : Figure out a better way to assert this!
  OBTAIN_EXECUTION_DOMAIN_TOKEN(token, owner_->mix_domain_);

  // Sanity check arguments.
  audio_sample_format_t driver_format;
  if (!driver_utils::AudioSampleFormatToDriverSampleFormat(fmt,
                                                           &driver_format)) {
    FXL_LOG(ERROR) << "Failed to convert Fmt 0x" << std::hex
                   << static_cast<uint32_t>(fmt) << " to driver format.";
    return ZX_ERR_INVALID_ARGS;
  }

  if (channels > std::numeric_limits<uint16_t>::max()) {
    FXL_LOG(ERROR) << "Bad channel count: " << channels;
    return ZX_ERR_INVALID_ARGS;
  }

  // TODO(johngro) : sanity check the min_ring_buffer_sz.

  // Check our known format list for compatibility.
  bool found_format = false;
  for (const auto& fmt_range : format_ranges_) {
    found_format = ::audio::utils::FormatIsCompatible(
        frames_per_second, channels, driver_format, fmt_range);
    if (found_format) {
      break;
    }
  }

  if (!found_format) {
    FXL_LOG(ERROR) << "No compatible format range found when setting format to "
                   << frames_per_second << " Hz " << channels << " Ch Fmt 0x"
                   << std::hex << static_cast<uint32_t>(fmt);
    return ZX_ERR_INVALID_ARGS;
  }

  // We must be in the Unconfigured state in order to change formats.
  // TODO(johngro): Improve this.  We should permit changing formats if we are
  // in either the Unconfigured or Configured state.
  if (state_ != State::Unconfigured) {
    FXL_LOG(ERROR) << "Bad state while attempting to configure for "
                   << frames_per_second << " Hz " << channels << " Ch Fmt 0x"
                   << std::hex << static_cast<uint32_t>(fmt)
                   << " (state = " << static_cast<uint32_t>(state_) << ")";
    return ZX_ERR_BAD_STATE;
  }

  // Record the details of our intended target format
  frames_per_sec_ = frames_per_second;
  channel_count_ = static_cast<uint16_t>(channels);
  sample_format_ = driver_format;
  bytes_per_frame_ =
      ::audio::utils::ComputeFrameSize(channel_count_, sample_format_);
  ;
  min_ring_buffer_duration_ = min_ring_buffer_duration;

  // Start the process of configuring by sending the message to set the format.
  audio_stream_cmd_set_format_req_t req;

  req.hdr.cmd = AUDIO_STREAM_CMD_SET_FORMAT;
  req.hdr.transaction_id = TXID;
  req.frames_per_second = frames_per_sec_;
  req.channels = channel_count_;
  req.sample_format = sample_format_;

  {
    std::lock_guard<std::mutex> lock(configured_format_lock_);
    configured_format_ = fuchsia::media::AudioStreamType::New();
    configured_format_->sample_format = fmt;
    configured_format_->channels = channels;
    configured_format_->frames_per_second = frames_per_second;
  }

  zx_status_t res = stream_channel_->Write(&req, sizeof(req));
  if (res != ZX_OK) {
    ShutdownSelf("Failed to send set format command", res);
    return res;
  }

  // Change state, setup our command timeout and we are finished.
  state_ = State::Configuring_SettingFormat;
  configuration_timeout_ = zx_deadline_after(kDefaultLongCmdTimeout);
  SetupCommandTimeout();

  return ZX_OK;
}

zx_status_t AudioDriver::Start() {
  // TODO(johngro) : Figure out a better way to assert this!
  OBTAIN_EXECUTION_DOMAIN_TOKEN(token, owner_->mix_domain_);

  // In order to start, we must be in the Configured state.
  //
  // Note: Attempting to start while already started is considered to be an
  // error because (since we are already started) we will never deliver the
  // OnDriverStartComplete callback, and it would be confisuing to do so from
  // within the call to start itself (before the user's call to Start even
  // returned)
  if (state_ != State::Configured) {
    FXL_LOG(ERROR) << "Bad state while attempting start (state = "
                   << static_cast<uint32_t>(state_) << ")";
    return ZX_ERR_BAD_STATE;
  }

  // Send the command to start the ring buffer.
  audio_rb_cmd_start_req_t req;
  req.hdr.cmd = AUDIO_RB_CMD_START;
  req.hdr.transaction_id = TXID;
  zx_status_t res = rb_channel_->Write(&req, sizeof(req));
  if (res != ZX_OK) {
    ShutdownSelf("Failed to send set start command", res);
    return res;
  }

  // Change state, setup our command timeout and we are finished.
  state_ = State::Starting;
  configuration_timeout_ = zx_deadline_after(kDefaultShortCmdTimeout);
  SetupCommandTimeout();

  return ZX_OK;
}

zx_status_t AudioDriver::Stop() {
  // TODO(johngro) : Figure out a better way to assert this!
  OBTAIN_EXECUTION_DOMAIN_TOKEN(token, owner_->mix_domain_);

  // In order to stop, we must be in the Started state.
  // TODO(johngro): consider relaxing this restriction to make Stop completely
  // idempotent.  Care would to be taken to handle the case where a user
  // attempts to stop while a start operation is in flight but has not
  // completed.  Allowing multiple start/stop operations to be in flight
  // simultaneously could get quite confusing.
  if (state_ != State::Started) {
    FXL_LOG(ERROR) << "Bad state while attempting stop (state = "
                   << static_cast<uint32_t>(state_) << ")";
    return ZX_ERR_BAD_STATE;
  }

  // Invalidate our timeline transformation here.  To outside observers, we are
  // now stopped.
  {
    std::lock_guard<std::mutex> lock(ring_buffer_state_lock_);
    clock_mono_to_ring_pos_bytes_ = TimelineFunction();
    ring_buffer_state_gen_.Next();
  }

  // Send the command to stop the ring buffer.
  audio_rb_cmd_start_req_t req;
  req.hdr.cmd = AUDIO_RB_CMD_STOP;
  req.hdr.transaction_id = TXID;
  zx_status_t res = rb_channel_->Write(&req, sizeof(req));
  if (res != ZX_OK) {
    ShutdownSelf("Failed to send set stop command", res);
    return res;
  }

  // Since we were just recently in steady state, we should be able to assert
  // that we have no configuration timeout at this point.
  FXL_DCHECK(configuration_timeout_ == ZX_TIME_INFINITE);

  // We are now in the process of stopping.
  state_ = State::Stopping;
  configuration_timeout_ = zx_deadline_after(kDefaultShortCmdTimeout);
  SetupCommandTimeout();

  return ZX_OK;
}

zx_status_t AudioDriver::SetPlugDetectEnabled(bool enabled) {
  // TODO(johngro) : Figure out a better way to assert this!
  OBTAIN_EXECUTION_DOMAIN_TOKEN(token, owner_->mix_domain_);

  if (enabled == pd_enabled_) {
    return ZX_OK;
  }

  audio_stream_cmd_plug_detect_req_t req;
  if (enabled) {
    req.hdr.cmd = AUDIO_STREAM_CMD_PLUG_DETECT;
    req.flags = AUDIO_PDF_ENABLE_NOTIFICATIONS;
    pd_enable_timeout_ = zx_deadline_after(kDefaultShortCmdTimeout);
  } else {
    req.hdr.cmd = static_cast<audio_cmd_t>(AUDIO_STREAM_CMD_PLUG_DETECT |
                                           AUDIO_FLAG_NO_ACK);
    req.flags = AUDIO_PDF_DISABLE_NOTIFICATIONS;
    pd_enable_timeout_ = ZX_TIME_INFINITE;
  }
  req.hdr.transaction_id = TXID;

  zx_status_t res = stream_channel_->Write(&req, sizeof(req));
  if (res != ZX_OK) {
    ShutdownSelf("Failed to request send plug state request", res);
    return res;
  }

  pd_enabled_ = enabled;
  SetupCommandTimeout();

  return ZX_OK;
}

zx_status_t AudioDriver::ReadMessage(::dispatcher::Channel* channel, void* buf,
                                     uint32_t buf_size,
                                     uint32_t* bytes_read_out,
                                     zx::handle* handle_out) {
  FXL_DCHECK(buf != nullptr);
  FXL_DCHECK(bytes_read_out != nullptr);
  FXL_DCHECK(handle_out != nullptr);
  FXL_DCHECK(buf_size >= sizeof(audio_cmd_hdr_t));

  if (!operational()) {
    return ZX_ERR_BAD_STATE;
  }

  zx_status_t res;
  res = channel->Read(buf, buf_size, bytes_read_out, handle_out);
  if (res != ZX_OK) {
    ShutdownSelf("Error attempting to read channel response", res);
    return res;
  }

  if (*bytes_read_out < sizeof(audio_cmd_hdr_t)) {
    FXL_LOG(ERROR) << "Channel response is too small to hold even a "
                   << "message header (" << *bytes_read_out << " < "
                   << sizeof(audio_cmd_hdr_t) << ").";
    ShutdownSelf("Channel response too small", ZX_ERR_INVALID_ARGS);
    return ZX_ERR_INVALID_ARGS;
  }

  return ZX_OK;
}

#define CHECK_RESP(_ioctl, _payload, _expect_handle, _is_notif)           \
  do {                                                                    \
    if ((_expect_handle) != rxed_handle.is_valid()) {                     \
      FXL_LOG(ERROR) << ((_expect_handle) ? "Missing" : "Unexpected")     \
                     << " handle in " #_ioctl " response";                \
      return ZX_ERR_INVALID_ARGS;                                         \
    }                                                                     \
    if ((msg.hdr.transaction_id == AUDIO_INVALID_TRANSACTION_ID) !=       \
        (_is_notif)) {                                                    \
      FXL_LOG(ERROR) << "Bad txn id " << msg.hdr.transaction_id           \
                     << " in " #_ioctl " response";                       \
      return ZX_ERR_INVALID_ARGS;                                         \
    }                                                                     \
    if (bytes_read != sizeof(msg._payload)) {                             \
      FXL_LOG(ERROR) << "Bad " #_ioctl " response length (" << bytes_read \
                     << " != " << sizeof(msg._payload) << ")";            \
      return ZX_ERR_INVALID_ARGS;                                         \
    }                                                                     \
  } while (0)

zx_status_t AudioDriver::ProcessStreamChannelMessage() {
  zx_status_t res;
  zx::handle rxed_handle;
  uint32_t bytes_read;
  union {
    audio_cmd_hdr_t hdr;
    audio_stream_cmd_get_unique_id_resp_t get_unique_id;
    audio_stream_cmd_get_string_resp_t get_string;
    audio_stream_cmd_get_gain_resp_t get_gain;
    audio_stream_cmd_get_formats_resp_t get_formats;
    audio_stream_cmd_set_format_resp_t set_format;
    audio_stream_cmd_plug_detect_resp_t pd_resp;
    audio_stream_plug_detect_notify_t pd_notify;
  } msg;
  static_assert(sizeof(msg) <= 256,
                "Message buffer is becoming too large to hold on the stack!");

  res = ReadMessage(stream_channel_.get(), &msg, sizeof(msg), &bytes_read,
                    &rxed_handle);
  if (res != ZX_OK) {
    return res;
  }

  bool plug_state;
  switch (msg.hdr.cmd) {
    case AUDIO_STREAM_CMD_GET_UNIQUE_ID:
      CHECK_RESP(AUDIO_STREAM_CMD_GET_UNIQUE_ID, get_unique_id, false, false);
      persistent_unique_id_ = msg.get_unique_id.unique_id;
      res = OnDriverInfoFetched(kDriverInfoHasUniqueId);
      break;

    case AUDIO_STREAM_CMD_GET_STRING:
      CHECK_RESP(AUDIO_STREAM_CMD_GET_STRING, get_string, false, false);
      res = ProcessGetStringResponse(msg.get_string);
      break;

    case AUDIO_STREAM_CMD_GET_GAIN:
      CHECK_RESP(AUDIO_STREAM_CMD_GET_GAIN, get_gain, false, false);
      res = ProcessGetGainResponse(msg.get_gain);
      break;

    case AUDIO_STREAM_CMD_GET_FORMATS:
      CHECK_RESP(AUDIO_STREAM_CMD_GET_FORMATS, get_formats, false, false);
      res = ProcessGetFormatsResponse(msg.get_formats);
      break;

    case AUDIO_STREAM_CMD_SET_FORMAT:
      CHECK_RESP(AUDIO_STREAM_CMD_SET_FORMAT, set_format, true, false);
      res = ProcessSetFormatResponse(msg.set_format,
                                     zx::channel(rxed_handle.release()));
      break;

    case AUDIO_STREAM_CMD_PLUG_DETECT:
      CHECK_RESP(AUDIO_STREAM_CMD_PLUG_DETECT, pd_resp, false, false);
      if ((msg.pd_resp.flags & AUDIO_PDNF_HARDWIRED) != 0) {
        plug_state = true;
      } else {
        plug_state = ((msg.pd_resp.flags & AUDIO_PDNF_PLUGGED) != 0);
        if ((msg.pd_resp.flags & AUDIO_PDNF_CAN_NOTIFY) == 0) {
          // TODO(johngro) : If we ever encounter hardware which must be polled
          // in order for plug detection to function properly, we should set up
          // a timer to periodically poll the plug state instead of just
          // assuming that the output is always plugged in.
          FXL_LOG(WARNING)
              << "Stream is incapable of async plug detection notifications.  "
                 "Assuming that the stream is always plugged in for now.";
          plug_state = true;
        }
      }

      ReportPlugStateChange(plug_state, msg.pd_resp.plug_state_time);

      pd_enable_timeout_ = ZX_TIME_INFINITE;
      SetupCommandTimeout();
      break;

    case AUDIO_STREAM_PLUG_DETECT_NOTIFY:
      CHECK_RESP(AUDIO_STREAM_CMD_PLUG_DETECT_NOTIFY, pd_notify, false, true);
      plug_state = ((msg.pd_notify.flags & AUDIO_PDNF_PLUGGED) != 0);
      ReportPlugStateChange(plug_state, msg.pd_notify.plug_state_time);
      break;

    default:
      FXL_LOG(ERROR) << "Unrecognized stream channel response 0x" << std::hex
                     << msg.hdr.cmd;
      return ZX_ERR_BAD_STATE;
  }

  if (res != ZX_OK) {
    ShutdownSelf("Error while processing stream channel message", res);
  }

  return res;
}

zx_status_t AudioDriver::ProcessRingBufferChannelMessage() {
  zx_status_t res;
  zx::handle rxed_handle;
  uint32_t bytes_read;
  union {
    audio_cmd_hdr_t hdr;
    audio_rb_cmd_get_fifo_depth_resp_t get_fifo_depth;
    audio_rb_cmd_get_buffer_resp_t get_buffer;
    audio_rb_cmd_start_resp_t start;
    audio_rb_cmd_stop_resp_t stop;
    audio_rb_position_notify_t pos_notify;
  } msg;
  static_assert(sizeof(msg) <= 256,
                "Message buffer is becoming too large to hold on the stack!");

  res = ReadMessage(rb_channel_.get(), &msg, sizeof(msg), &bytes_read,
                    &rxed_handle);
  if (res != ZX_OK) {
    return res;
  }

  switch (msg.hdr.cmd) {
    case AUDIO_RB_CMD_GET_FIFO_DEPTH:
      CHECK_RESP(AUDIO_RB_CMD_GET_FIFO_DEPTH, get_fifo_depth, false, false);
      res = ProcessGetFifoDepthResponse(msg.get_fifo_depth);
      break;

    case AUDIO_RB_CMD_GET_BUFFER:
      CHECK_RESP(AUDIO_RB_CMD_GET_BUFFER, get_buffer, true, false);
      res = ProcessGetBufferResponse(msg.get_buffer,
                                     zx::vmo(rxed_handle.release()));
      break;

    case AUDIO_RB_CMD_START:
      CHECK_RESP(AUDIO_RB_CMD_START, start, false, false);
      res = ProcessStartResponse(msg.start);
      break;

    case AUDIO_RB_CMD_STOP:
      CHECK_RESP(AUDIO_RB_CMD_STOP, stop, false, false);
      res = ProcessStopResponse(msg.stop);
      break;

    // Currently we ignore driver-reported position, instead using the system-
    // internal clock. This message is benign and can be safely ignored, but
    // because we did not request it, this may indicate some other problem in
    // the driver state machine. We issue a warning, eat the msg and continue.
    case AUDIO_RB_POSITION_NOTIFY:
      CHECK_RESP(AUDIO_RB_POSITION_NOTIFY, pos_notify, false, true);
      res = ProcessPositionNotify(msg.pos_notify);
      break;

    default:
      FXL_LOG(ERROR) << "Unrecognized ring buffer channel response 0x"
                     << std::hex << msg.hdr.cmd;
      return ZX_ERR_BAD_STATE;
  }

  if (res != ZX_OK) {
    ShutdownSelf("Error while processing ring buffer message", res);
  }

  return res;
}
#undef CHECK_RESP

zx_status_t AudioDriver::ProcessGetStringResponse(
    audio_stream_cmd_get_string_resp_t& resp) {
  std::string* tgt_string;
  uint32_t info_bit;

  if (state_ != State::MissingDriverInfo) {
    FXL_LOG(ERROR) << "Bad state (" << static_cast<uint32_t>(state_)
                   << ") while handling get string response.";
    return ZX_ERR_BAD_STATE;
  }

  if (resp.result != ZX_OK) {
    FXL_LOG(WARNING) << "Error ( " << resp.result
                     << ") attempting to fetch string id " << resp.id
                     << ".  Replacing with <unknown>.";
    resp.strlen = static_cast<uint32_t>(snprintf(
        reinterpret_cast<char*>(resp.str), sizeof(resp.str), "<unknown>"));
  }

  switch (resp.id) {
    case AUDIO_STREAM_STR_ID_MANUFACTURER:
      info_bit = kDriverInfoHasMfrStr;
      tgt_string = &manufacturer_name_;
      break;

    case AUDIO_STREAM_STR_ID_PRODUCT:
      info_bit = kDriverInfoHasProdStr;
      tgt_string = &product_name_;
      break;

    default:
      FXL_LOG(ERROR) << "Unrecognized string id (" << resp.id << ").";
      return ZX_ERR_INVALID_ARGS;
  }

  if (resp.strlen > sizeof(resp.str)) {
    FXL_LOG(ERROR) << "Bad string length " << resp.strlen
                   << " attempting to fetch string id " << resp.id << ".";
    return ZX_ERR_INTERNAL;
  }

  // Stash the string we just received and update our progress in fetching our
  // initial driver info.
  FXL_DCHECK(tgt_string != nullptr);
  tgt_string->assign(reinterpret_cast<char*>(resp.str), resp.strlen);
  return OnDriverInfoFetched(info_bit);
}

zx_status_t AudioDriver::ProcessGetGainResponse(
    audio_stream_cmd_get_gain_resp_t& resp) {
  hw_gain_state_.cur_mute = resp.cur_mute;
  hw_gain_state_.cur_agc = resp.cur_agc;
  hw_gain_state_.cur_gain = resp.cur_gain;
  hw_gain_state_.can_mute = resp.can_mute;
  hw_gain_state_.can_agc = resp.can_agc;
  hw_gain_state_.min_gain = resp.min_gain;
  hw_gain_state_.max_gain = resp.max_gain;
  hw_gain_state_.gain_step = resp.gain_step;

  return OnDriverInfoFetched(kDriverInfoHasGainState);
}

zx_status_t AudioDriver::ProcessGetFormatsResponse(
    const audio_stream_cmd_get_formats_resp_t& resp) {
  if (!fetching_driver_info()) {
    FXL_LOG(ERROR) << "Received unsolicited get formats response.";
    return ZX_ERR_BAD_STATE;
  }

  // Is this the first response?  If so, resize our format vector
  // before proceeding.
  if (resp.first_format_range_ndx == 0) {
    format_ranges_.reserve(resp.format_range_count);
  }

  // Sanity checks
  if (resp.format_range_count == 0) {
    FXL_LOG(ERROR) << "Driver reported that it supports no format ranges!";
    return ZX_ERR_INVALID_ARGS;
  }

  if (resp.first_format_range_ndx >= resp.format_range_count) {
    FXL_LOG(ERROR) << "Bad format range index in get formats response! (index "
                   << resp.first_format_range_ndx << " should be < total "
                   << resp.format_range_count << ")";
    return ZX_ERR_INVALID_ARGS;
  }

  if (resp.first_format_range_ndx != format_ranges_.size()) {
    FXL_LOG(ERROR) << "Out of order message in get formats response! (index "
                   << resp.first_format_range_ndx << " != the expected "
                   << format_ranges_.size() << ")";
    return ZX_ERR_INVALID_ARGS;
  }

  // Add this set of formats to our list.
  uint16_t todo =
      std::min<uint16_t>(resp.format_range_count - resp.first_format_range_ndx,
                         AUDIO_STREAM_CMD_GET_FORMATS_MAX_RANGES_PER_RESPONSE);
  for (uint16_t i = 0; i < todo; ++i) {
    format_ranges_.emplace_back(resp.format_ranges[i]);
  }

  // Record the fact that we have now fetched our format list.  This will handle
  // transitioning to the Unconfigured state and letting our owner know if we
  // have managed to fetch all of the initial driver info we need to operate.
  return OnDriverInfoFetched(kDriverInfoHasFormats);
}

zx_status_t AudioDriver::ProcessSetFormatResponse(
    const audio_stream_cmd_set_format_resp_t& resp, zx::channel rb_channel) {
  if (state_ != State::Configuring_SettingFormat) {
    FXL_LOG(ERROR) << "Received unexpected set format response while in state "
                   << static_cast<uint32_t>(state_);
    return ZX_ERR_BAD_STATE;
  }

  if (resp.result != ZX_OK) {
    FXL_LOG(WARNING) << "Error attempting to set format: " << frames_per_sec_
                     << "Hz " << channel_count_ << "-Ch 0x" << std::hex
                     << sample_format_ << "(res " << std::dec << resp.result
                     << ")";
    return resp.result;
  }

  // TODO(johngro): See MTWN-61. Update AudioCapturers and outputs to take
  // external delay into account when sampling.
  external_delay_nsec_ = resp.external_delay_nsec;

  // Activate our ring buffer channel in our execution domain.
  ::dispatcher::Channel::ProcessHandler process_handler(
      [this](::dispatcher::Channel* channel) -> zx_status_t {
        OBTAIN_EXECUTION_DOMAIN_TOKEN(token, owner_->mix_domain_);
        FXL_DCHECK(rb_channel_.get() == channel);
        return ProcessRingBufferChannelMessage();
      });

  ::dispatcher::Channel::ChannelClosedHandler channel_closed_handler(
      [this](const ::dispatcher::Channel* channel) {
        OBTAIN_EXECUTION_DOMAIN_TOKEN(token, owner_->mix_domain_);
        FXL_DCHECK(rb_channel_.get() == channel);
        ShutdownSelf("Ring buffer channel closed");
      });

  zx_status_t res;
  res = rb_channel_->Activate(std::move(rb_channel), owner_->mix_domain_,
                              std::move(process_handler),
                              std::move(channel_closed_handler));
  if (res != ZX_OK) {
    FXL_LOG(ERROR) << "Failed to activate ring buffer channel (res = " << res
                   << ")";
    return res;
  }

  // Fetch the fifo depth of the ring buffer we just got back.  This determines
  // how far ahead of the current playout position (in bytes) the hardware may
  // read.  We need to know this number in order to size the ring buffer vmo
  // appropriately
  audio_rb_cmd_get_fifo_depth_req req;

  req.hdr.cmd = AUDIO_RB_CMD_GET_FIFO_DEPTH;
  req.hdr.transaction_id = TXID;

  res = rb_channel_->Write(&req, sizeof(req));
  if (res != ZX_OK) {
    FXL_LOG(ERROR) << "Failed to request ring buffer fifo depth.";
    return res;
  }

  // Things went well, proceed to the next step in the state machine.
  state_ = State::Configuring_GettingFifoDepth;
  configuration_timeout_ = zx_deadline_after(kDefaultShortCmdTimeout);
  SetupCommandTimeout();
  return ZX_OK;
}

zx_status_t AudioDriver::ProcessGetFifoDepthResponse(
    const audio_rb_cmd_get_fifo_depth_resp_t& resp) {
  if (state_ != State::Configuring_GettingFifoDepth) {
    FXL_LOG(ERROR) << "Received unexpected fifo depth response while in state "
                   << static_cast<uint32_t>(state_);
    return ZX_ERR_BAD_STATE;
  }

  if (resp.result != ZX_OK) {
    FXL_LOG(ERROR) << "Error when fetching ring buffer fifo depth (res = "
                   << resp.result << ").";
    return resp.result;
  }

  fifo_depth_bytes_ = resp.fifo_depth;
  fifo_depth_frames_ =
      (fifo_depth_bytes_ + bytes_per_frame_ - 1) / bytes_per_frame_;

  // Figure out how many frames we need in our ring buffer.
  int64_t min_frames_64 = TimelineRate::Scale(
      min_ring_buffer_duration_, bytes_per_frame_ * frames_per_sec_, ZX_SEC(1));
  int64_t overhead =
      static_cast<int64_t>(fifo_depth_bytes_) + bytes_per_frame_ - 1;
  bool overflow =
      ((min_frames_64 == TimelineRate::kOverflow) ||
       (min_frames_64 > (std::numeric_limits<int64_t>::max() - overhead)));

  if (!overflow) {
    min_frames_64 += overhead;
    min_frames_64 /= bytes_per_frame_;
    overflow = min_frames_64 > std::numeric_limits<uint32_t>::max();
  }

  if (overflow) {
    FXL_LOG(ERROR)
        << "Overflow while attempting to compute ring buffer size in frames.";
    FXL_LOG(ERROR) << "duration        : " << min_ring_buffer_duration_;
    FXL_LOG(ERROR) << "bytes per frame : " << bytes_per_frame_;
    FXL_LOG(ERROR) << "frames per sec  : " << frames_per_sec_;
    FXL_LOG(ERROR) << "fifo depth      : " << fifo_depth_bytes_;
    FXL_LOG(ERROR) << "bytes per frame : " << bytes_per_frame_;
    return ZX_ERR_INTERNAL;
  }

  // Request the ring buffer.
  audio_rb_cmd_get_buffer_req_t req;
  req.hdr.cmd = AUDIO_RB_CMD_GET_BUFFER;
  req.hdr.transaction_id = TXID;
  req.min_ring_buffer_frames = static_cast<uint32_t>(min_frames_64);
  req.notifications_per_ring = 0;

  zx_status_t res = rb_channel_->Write(&req, sizeof(req));
  if (res != ZX_OK) {
    ShutdownSelf("Failed to request ring buffer vmo", res);
    return res;
  }

  state_ = State::Configuring_GettingRingBuffer;
  configuration_timeout_ = zx_deadline_after(kDefaultShortCmdTimeout);
  SetupCommandTimeout();
  return ZX_OK;
}

zx_status_t AudioDriver::ProcessGetBufferResponse(
    const audio_rb_cmd_get_buffer_resp_t& resp, zx::vmo rb_vmo) {
  if (state_ != State::Configuring_GettingRingBuffer) {
    FXL_LOG(ERROR) << "Received unexpected get buffer response while in state "
                   << static_cast<uint32_t>(state_);
    return ZX_ERR_BAD_STATE;
  }

  if (resp.result != ZX_OK) {
    ShutdownSelf("Error when fetching ring buffer vmo", resp.result);
    return resp.result;
  }

  {
    std::lock_guard<std::mutex> lock(ring_buffer_state_lock_);

    ring_buffer_ = DriverRingBuffer::Create(std::move(rb_vmo), bytes_per_frame_,
                                            resp.num_ring_buffer_frames,
                                            owner_->is_input());
    if (ring_buffer_ == nullptr) {
      ShutdownSelf("Failed to allocate and map driver ring buffer",
                   ZX_ERR_NO_MEMORY);
      return ZX_ERR_NO_MEMORY;
    }
    FXL_DCHECK(!clock_mono_to_ring_pos_bytes_.invertible());

    ring_buffer_state_gen_.Next();
  }

  // We are now configured.  Let our owner know about this important milestone.
  state_ = State::Configured;
  configuration_timeout_ = ZX_TIME_INFINITE;
  SetupCommandTimeout();
  owner_->OnDriverConfigComplete();
  return ZX_OK;
}

zx_status_t AudioDriver::ProcessStartResponse(
    const audio_rb_cmd_start_resp_t& resp) {
  if (state_ != State::Starting) {
    FXL_LOG(ERROR) << "Received unexpected start response while in state "
                   << static_cast<uint32_t>(state_);
    return ZX_ERR_BAD_STATE;
  }

  if (resp.result != ZX_OK) {
    ShutdownSelf("Error when starting ring buffer", resp.result);
    return resp.result;
  }

  // Now that we have started up, compute the transformation from clock
  // monotonic to the ring buffer position (in bytes) Then update the ring
  // buffer state's transformation and bump the generation counter.
  TimelineFunction func(0, resp.start_time, frames_per_sec_ * bytes_per_frame_,
                        ZX_SEC(1));
  {
    std::lock_guard<std::mutex> lock(ring_buffer_state_lock_);
    FXL_DCHECK(!clock_mono_to_ring_pos_bytes_.invertible());
    FXL_DCHECK(ring_buffer_ != nullptr);
    clock_mono_to_ring_pos_bytes_ = func;
    ring_buffer_state_gen_.Next();
  }

  // We are now started. Let our owner know about this important milestone.
  state_ = State::Started;
  configuration_timeout_ = ZX_TIME_INFINITE;
  SetupCommandTimeout();
  owner_->OnDriverStartComplete();
  return ZX_OK;
}

zx_status_t AudioDriver::ProcessStopResponse(
    const audio_rb_cmd_stop_resp_t& resp) {
  if (state_ != State::Stopping) {
    FXL_LOG(ERROR) << "Received unexpected stop response while in state "
                   << static_cast<uint32_t>(state_);
    return ZX_ERR_BAD_STATE;
  }

  if (resp.result != ZX_OK) {
    ShutdownSelf("Error when stopping ring buffer", resp.result);
    return resp.result;
  }

  // We are now stopped.  Let our owner know about this important milestone.
  state_ = State::Configured;
  configuration_timeout_ = ZX_TIME_INFINITE;
  SetupCommandTimeout();
  owner_->OnDriverStopComplete();
  return ZX_OK;
}

zx_status_t AudioDriver::ProcessPositionNotify(
    const audio_rb_position_notify_t& notify) {
  FXL_DLOG(INFO) << "Unsolicited ring buffer position notification!  Time:"
                 << zx_clock_get_monotonic()
                 << " Pos:" << notify.ring_buffer_pos;

  // Although this notification was unsolicited and unexpected, we only complain
  // (and only on debug builds), rather than abort-closing the channel.
  return ZX_OK;
}

void AudioDriver::ShutdownSelf(const char* reason, zx_status_t status) {
  if (state_ == State::Shutdown) {
    return;
  }

  if (reason != nullptr) {
    FXL_LOG(INFO) << (owner_->is_input() ? " Input" : "Output")
                  << " shutting down '" << reason << "', status:" << status;
  }

  // Our owner will call our Cleanup function within this call.
  owner_->ShutdownSelf();
  state_ = State::Shutdown;
}

void AudioDriver::SetupCommandTimeout() {
  zx_time_t timeout;

  timeout = fetch_driver_info_timeout_;
  timeout = fbl::min(timeout, configuration_timeout_);
  timeout = fbl::min(timeout, pd_enable_timeout_);

  if (last_set_timeout_ != timeout) {
    if (timeout != ZX_TIME_INFINITE) {
      cmd_timeout_->Arm(timeout);
    } else {
      cmd_timeout_->Cancel();
    }
    last_set_timeout_ = timeout;
  }
}

void AudioDriver::ReportPlugStateChange(bool plugged, zx_time_t plug_time) {
  {
    fbl::AutoLock lock(&plugged_lock_);
    plugged_ = plugged;
    plug_time_ = plug_time;
  }

  if (pd_enabled_) {
    owner_->OnDriverPlugStateChange(plugged, plug_time);
  }
}

zx_status_t AudioDriver::OnDriverInfoFetched(uint32_t info) {
  // We should never fetch the same info twice.
  if (fetched_driver_info_ & info) {
    ShutdownSelf("Duplicate driver info fetch\n", ZX_ERR_BAD_STATE);
    return ZX_ERR_BAD_STATE;
  }

  // Record the new piece of info we just fetched.
  FXL_DCHECK(state_ == State::MissingDriverInfo);
  fetched_driver_info_ |= info;

  // Have we finished fetching our initial driver info?  If so, cancel the
  // timeout, transition to the unconfigured state, and let our owner know that
  // we have finished.
  if ((fetched_driver_info_ & kDriverInfoHasAll) == kDriverInfoHasAll) {
    // We are done.  Clear the fetch driver info timeout and let our owner know.
    fetch_driver_info_timeout_ = ZX_TIME_INFINITE;
    state_ = State::Unconfigured;
    SetupCommandTimeout();
    owner_->OnDriverInfoFetched();
  }

  return ZX_OK;
}

zx_status_t AudioDriver::SendSetGain(
    const AudioDeviceSettings::GainState& gain_state,
    audio_set_gain_flags_t set_flags) {
  audio_stream_cmd_set_gain_req_t req;
  req.hdr.cmd =
      static_cast<audio_cmd_t>(AUDIO_STREAM_CMD_SET_GAIN | AUDIO_FLAG_NO_ACK);
  req.hdr.transaction_id = TXID;

  // clang-format off
  req.flags = static_cast<audio_set_gain_flags_t>(
      set_flags |
      (gain_state.muted ? AUDIO_SGF_MUTE : 0) |
      (gain_state.agc_enabled ? AUDIO_SGF_AGC : 0));
  // clang-format on
  req.gain = gain_state.gain_db;

  return stream_channel_->Write(&req, sizeof(req));
}

}  // namespace media::audio
