/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "BTAudioHalStream"

#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <cutils/properties.h>
#include <errno.h>
#include <inttypes.h>
#include <log/log.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include "stream_apis.h"
#include "utils.h"

using ::android::base::StringPrintf;
using ::android::bluetooth::audio::BluetoothAudioPortOut;
using ::android::bluetooth::audio::utils::GetAudioParamString;
using ::android::bluetooth::audio::utils::ParseAudioParams;

namespace {

constexpr unsigned int kMinimumDelayMs = 50;
constexpr unsigned int kMaximumDelayMs = 1000;
constexpr int kExtraAudioSyncMs = 200;

std::ostream& operator<<(std::ostream& os, const audio_config& config) {
  return os << "audio_config[sample_rate=" << config.sample_rate
            << ", channels=" << StringPrintf("%#x", config.channel_mask)
            << ", format=" << config.format << "]";
}

void out_calculate_feeding_delay_ms(const BluetoothStreamOut* out,
                                    uint32_t* latency_ms,
                                    uint64_t* frames = nullptr,
                                    struct timespec* timestamp = nullptr) {
  if (latency_ms == nullptr && frames == nullptr && timestamp == nullptr) {
    return;
  }

  // delay_report is the audio delay from the remote headset receiving data to
  // the headset playing sound in units of nanoseconds
  uint64_t delay_report_ns = 0;
  uint64_t delay_report_ms = 0;
  // absorbed_bytes is the total number of bytes sent by the Bluetooth stack to
  // a remote headset
  uint64_t absorbed_bytes = 0;
  // absorbed_timestamp is the ...
  struct timespec absorbed_timestamp = {};
  bool timestamp_fetched = false;

  std::unique_lock<std::mutex> lock(out->mutex_);
  if (out->bluetooth_output_.GetPresentationPosition(
          &delay_report_ns, &absorbed_bytes, &absorbed_timestamp)) {
    delay_report_ms = delay_report_ns / 1000000;
    // assume kMinimumDelayMs (50ms) < delay_report_ns < kMaximumDelayMs
    // (1000ms), or it is invalid / ignored and use old delay calculated
    // by ourselves.
    if (delay_report_ms > kMinimumDelayMs &&
        delay_report_ms < kMaximumDelayMs) {
      timestamp_fetched = true;
    } else if (delay_report_ms >= kMaximumDelayMs) {
      LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                << ", delay_report=" << delay_report_ns << "ns abnormal";
    }
  }
  if (!timestamp_fetched) {
    // default to old delay if any failure is found when fetching from ports
    // audio_a2dp_hw:
    //   frames_count = buffer_size / frame_size
    //   latency (sec.) = frames_count / samples_per_second (sample_rate)
    // Sync from audio_a2dp_hw to add extra delay kExtraAudioSyncMs(+200ms)
    delay_report_ms =
        out->frames_count_ * 1000 / out->sample_rate_ + kExtraAudioSyncMs;
    if (timestamp != nullptr) {
      clock_gettime(CLOCK_MONOTONIC, &absorbed_timestamp);
    }
    LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                 << " uses the legacy delay " << delay_report_ms << " ms";
  }
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", delay=" << delay_report_ms << "ms, data=" << absorbed_bytes
               << " bytes, timestamp=" << absorbed_timestamp.tv_sec << "."
               << StringPrintf("%09ld", absorbed_timestamp.tv_nsec) << "s";

  if (latency_ms != nullptr) {
    *latency_ms = delay_report_ms;
  }
  if (frames != nullptr) {
    const uint64_t latency_frames = delay_report_ms * out->sample_rate_ / 1000;
    *frames = absorbed_bytes / audio_stream_out_frame_size(&out->stream_out_);
    if (out->frames_presented_ < *frames) {
      // Are we (the audio HAL) reset?! The stack counter is obsoleted.
      *frames = out->frames_presented_;
    } else if ((out->frames_presented_ - *frames) > latency_frames) {
      // Is the Bluetooth output reset / restarted by AVDTP reconfig?! Its
      // counter was reset but could not be used.
      *frames = out->frames_presented_;
    }
    // suppose frames would be queued in the headset buffer for delay_report
    // period, so those frames in buffers should not be included in the number
    // of presented frames at the timestamp.
    if (*frames > latency_frames) {
      *frames -= latency_frames;
    } else {
      *frames = 0;
    }
  }
  if (timestamp != nullptr) {
    *timestamp = absorbed_timestamp;
  }
}

void in_calculate_starving_delay_ms(const BluetoothStreamIn* in,
                                    int64_t* frames, int64_t* time) {
  // delay_report is the audio delay from the remote headset receiving data to
  // the headset playing sound in units of nanoseconds
  uint64_t delay_report_ns = 0;
  uint64_t delay_report_ms = 0;
  // dispersed_bytes is the total number of bytes received by the Bluetooth
  // stack from a remote headset
  uint64_t dispersed_bytes = 0;
  struct timespec dispersed_timestamp = {};

  std::unique_lock<std::mutex> lock(in->mutex_);
  in->bluetooth_input_.GetPresentationPosition(
      &delay_report_ns, &dispersed_bytes, &dispersed_timestamp);
  delay_report_ms = delay_report_ns / 1000000;

  const uint64_t latency_frames = delay_report_ms * in->sample_rate_ / 1000;
  *frames = dispersed_bytes / audio_stream_in_frame_size(&in->stream_in_);

  LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
               << ", delay=" << delay_report_ms
               << "ms, data=" << dispersed_bytes
               << " bytes, timestamp=" << dispersed_timestamp.tv_sec << "."
               << StringPrintf("%09ld", dispersed_timestamp.tv_nsec) << "s";

  if (in->frames_presented_ < *frames) {
    // Was audio HAL reset?! The stack counter is obsoleted.
    *frames = in->frames_presented_;
  } else if ((in->frames_presented_ - *frames) > latency_frames) {
    // Is the Bluetooth input reset ?! Its counter was reset but could not be
    // used.
    *frames = in->frames_presented_;
  }
  // suppose frames would be queued in the headset buffer for delay_report
  // period, so those frames in buffers should not be included in the number
  // of presented frames at the timestamp.
  if (*frames > latency_frames) {
    *frames -= latency_frames;
  } else {
    *frames = 0;
  }

  *time = (dispersed_timestamp.tv_sec * 1000000000LL +
           dispersed_timestamp.tv_nsec) /
          1000;
}

}  // namespace

std::ostream& operator<<(std::ostream& os, const BluetoothStreamState& state) {
  switch (state) {
    case BluetoothStreamState::DISABLED:
      return os << "DISABLED";
    case BluetoothStreamState::STANDBY:
      return os << "STANDBY";
    case BluetoothStreamState::STARTING:
      return os << "STARTING";
    case BluetoothStreamState::STARTED:
      return os << "STARTED";
    case BluetoothStreamState::SUSPENDING:
      return os << "SUSPENDING";
    case BluetoothStreamState::UNKNOWN:
      return os << "UNKNOWN";
    default:
      return os << StringPrintf("%#hhx", state);
  }
}

static uint32_t out_get_sample_rate(const struct audio_stream* stream) {
  const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
  audio_config_t audio_cfg;
  if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
    LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                 << " audio_cfg=" << audio_cfg;
    return audio_cfg.sample_rate;
  } else {
    LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                 << ", sample_rate=" << out->sample_rate_ << " failed";
    return out->sample_rate_;
  }
}

static int out_set_sample_rate(struct audio_stream* stream, uint32_t rate) {
  auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", sample_rate=" << out->sample_rate_;
  return (rate == out->sample_rate_ ? 0 : -1);
}

static size_t out_get_buffer_size(const struct audio_stream* stream) {
  const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
  size_t buffer_size =
      out->frames_count_ * audio_stream_out_frame_size(&out->stream_out_);
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", buffer_size=" << buffer_size;
  return buffer_size;
}

static audio_channel_mask_t out_get_channels(
    const struct audio_stream* stream) {
  const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
  audio_config_t audio_cfg;
  if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
    LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                 << " audio_cfg=" << audio_cfg;
    return audio_cfg.channel_mask;
  } else {
    LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                 << ", channels=" << StringPrintf("%#x", out->channel_mask_) << " failure";
    return out->channel_mask_;
  }
}

static audio_format_t out_get_format(const struct audio_stream* stream) {
  const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
  audio_config_t audio_cfg;
  if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
    LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                 << " audio_cfg=" << audio_cfg;
    return audio_cfg.format;
  } else {
    LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                 << ", format=" << out->format_ << " failure";
    return out->format_;
  }
}

static int out_set_format(struct audio_stream* stream, audio_format_t format) {
  auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", format=" << out->format_;
  return (format == out->format_ ? 0 : -1);
}

static int out_standby(struct audio_stream* stream) {
  auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
  std::unique_lock<std::mutex> lock(out->mutex_);
  int retval = 0;

  // out->last_write_time_us_ = 0; unnecessary as a stale write time has same
  // effect
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << " being standby (suspend)";
  if (out->bluetooth_output_.GetState() == BluetoothStreamState::STARTED) {
    out->frames_rendered_ = 0;
    retval = (out->bluetooth_output_.Suspend() ? 0 : -EIO);
  } else if (out->bluetooth_output_.GetState() ==
                 BluetoothStreamState::STARTING ||
             out->bluetooth_output_.GetState() ==
                 BluetoothStreamState::SUSPENDING) {
    LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                 << " NOT ready to be standby";
    retval = -EBUSY;
  } else {
    LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << " standby already";
  }
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << " standby (suspend) retval=" << retval;

  return retval;
}

static int out_dump(const struct audio_stream* stream, int fd) {
  const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState();
  return 0;
}

static int out_set_parameters(struct audio_stream* stream,
                              const char* kvpairs) {
  auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
  std::unique_lock<std::mutex> lock(out->mutex_);
  int retval = 0;

  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", kvpairs=[" << kvpairs << "]";

  std::unordered_map<std::string, std::string> params =
      ParseAudioParams(kvpairs);
  if (params.empty()) return retval;

  LOG(VERBOSE) << __func__ << ": ParamsMap=[" << GetAudioParamString(params)
               << "]";

  audio_config_t audio_cfg;
  if (params.find(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES) != params.end() ||
      params.find(AUDIO_PARAMETER_STREAM_SUP_CHANNELS) != params.end() ||
      params.find(AUDIO_PARAMETER_STREAM_SUP_FORMATS) != params.end()) {
    if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
      out->sample_rate_ = audio_cfg.sample_rate;
      out->channel_mask_ = audio_cfg.channel_mask;
      out->format_ = audio_cfg.format;
      LOG(VERBOSE) << "state=" << out->bluetooth_output_.GetState() << ", sample_rate=" << out->sample_rate_
                   << ", channels=" << StringPrintf("%#x", out->channel_mask_) << ", format=" << out->format_;
    } else {
      LOG(WARNING) << __func__
                   << ": state=" << out->bluetooth_output_.GetState()
                   << " failed to get audio config";
    }
  }

  if (params.find("routing") != params.end()) {
    auto routing_param = params.find("routing");
    LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
              << ", stream param '" << routing_param->first.c_str() << "="
              << routing_param->second.c_str() << "'";
  }

  if (params.find("A2dpSuspended") != params.end() &&
      out->bluetooth_output_.IsA2dp()) {
    if (params["A2dpSuspended"] == "true") {
      LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                << " stream param stopped";
      out->frames_rendered_ = 0;
      if (out->bluetooth_output_.GetState() == BluetoothStreamState::STARTED) {
        out->bluetooth_output_.Suspend();
        out->bluetooth_output_.SetState(BluetoothStreamState::DISABLED);
      } else if (out->bluetooth_output_.GetState() !=
                 BluetoothStreamState::DISABLED) {
        out->bluetooth_output_.Stop();
      }
    } else {
      LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                << " stream param standby";
      if (out->bluetooth_output_.GetState() == BluetoothStreamState::DISABLED) {
        out->bluetooth_output_.SetState(BluetoothStreamState::STANDBY);
      }
    }
  }

  if (params.find("closing") != params.end()) {
    if (params["closing"] == "true") {
      LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                << " stream param closing, disallow any writes?";
      if (out->bluetooth_output_.GetState() != BluetoothStreamState::DISABLED) {
        out->frames_rendered_ = 0;
        out->frames_presented_ = 0;
        out->bluetooth_output_.Stop();
      }
    }
  }

  if (params.find("exiting") != params.end()) {
    if (params["exiting"] == "1") {
      LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                << " stream param exiting";
      if (out->bluetooth_output_.GetState() != BluetoothStreamState::DISABLED) {
        out->frames_rendered_ = 0;
        out->frames_presented_ = 0;
        out->bluetooth_output_.Stop();
      }
    }
  }

  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", kvpairs=[" << kvpairs << "], retval=" << retval;
  return retval;
}

static char* out_get_parameters(const struct audio_stream* stream,
                                const char* keys) {
  const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
  std::unique_lock<std::mutex> lock(out->mutex_);

  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", keys=[" << keys << "]";

  std::unordered_map<std::string, std::string> params = ParseAudioParams(keys);
  if (params.empty()) return strdup("");

  audio_config_t audio_cfg;
  if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
    LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                 << " audio_cfg=" << audio_cfg;
  } else {
    LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << " failed to get audio config";
  }

  std::unordered_map<std::string, std::string> return_params;
  if (params.find(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES) != params.end()) {
    std::string param;
    if (audio_cfg.sample_rate == 16000) {
      param = "16000";
    }
    if (audio_cfg.sample_rate == 24000) {
      param = "24000";
    }
    if (audio_cfg.sample_rate == 44100) {
      param = "44100";
    }
    if (audio_cfg.sample_rate == 48000) {
      param = "48000";
    }
    if (audio_cfg.sample_rate == 88200) {
      param = "88200";
    }
    if (audio_cfg.sample_rate == 96000) {
      param = "96000";
    }
    if (audio_cfg.sample_rate == 176400) {
      param = "176400";
    }
    if (audio_cfg.sample_rate == 192000) {
      param = "192000";
    }
    return_params[AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES] = param;
  }

  if (params.find(AUDIO_PARAMETER_STREAM_SUP_CHANNELS) != params.end()) {
    std::string param;
    if (audio_cfg.channel_mask == AUDIO_CHANNEL_OUT_MONO) {
      param = "AUDIO_CHANNEL_OUT_MONO";
    }
    if (audio_cfg.channel_mask == AUDIO_CHANNEL_OUT_STEREO) {
      param = "AUDIO_CHANNEL_OUT_STEREO";
    }
    return_params[AUDIO_PARAMETER_STREAM_SUP_CHANNELS] = param;
  }

  if (params.find(AUDIO_PARAMETER_STREAM_SUP_FORMATS) != params.end()) {
    std::string param;
    if (audio_cfg.format == AUDIO_FORMAT_PCM_16_BIT) {
      param = "AUDIO_FORMAT_PCM_16_BIT";
    }
    if (audio_cfg.format == AUDIO_FORMAT_PCM_24_BIT_PACKED) {
      param = "AUDIO_FORMAT_PCM_24_BIT_PACKED";
    }
    if (audio_cfg.format == AUDIO_FORMAT_PCM_32_BIT) {
      param = "AUDIO_FORMAT_PCM_32_BIT";
    }
    return_params[AUDIO_PARAMETER_STREAM_SUP_FORMATS] = param;
  }

  std::string result;
  for (const auto& ptr : return_params) {
    result += ptr.first + "=" + ptr.second + ";";
  }

  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", result=[" << result << "]";
  return strdup(result.c_str());
}

static uint32_t out_get_latency_ms(const struct audio_stream_out* stream) {
  const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
  uint32_t latency_ms = 0;
  out_calculate_feeding_delay_ms(out, &latency_ms);
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", latency=" << latency_ms << "ms";
  return latency_ms;
}

static int out_set_volume(struct audio_stream_out* stream, float left,
                          float right) {
  auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", Left=" << left << ", Right=" << right;
  return -1;
}

static ssize_t out_write(struct audio_stream_out* stream, const void* buffer,
                         size_t bytes) {
  auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
  std::unique_lock<std::mutex> lock(out->mutex_);
  size_t totalWritten = 0;

  if (out->bluetooth_output_.GetState() != BluetoothStreamState::STARTED) {
    LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
              << " first time bytes=" << bytes;
    lock.unlock();
    if (stream->resume(stream)) {
      LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                 << " failed to resume";
      if (out->bluetooth_output_.GetState() == BluetoothStreamState::DISABLED) {
        // drop data for cases of A2dpSuspended=true / closing=true
        totalWritten = bytes;
      }
      usleep(kBluetoothDefaultOutputBufferMs * 1000);
      return totalWritten;
    }
    lock.lock();
  }
  lock.unlock();
  totalWritten = out->bluetooth_output_.WriteData(buffer, bytes);
  lock.lock();

  struct timespec ts = {.tv_sec = 0, .tv_nsec = 0};
  clock_gettime(CLOCK_MONOTONIC, &ts);
  if (totalWritten) {
    const size_t frames = bytes / audio_stream_out_frame_size(stream);
    out->frames_rendered_ += frames;
    out->frames_presented_ += frames;
    out->last_write_time_us_ = (ts.tv_sec * 1000000000LL + ts.tv_nsec) / 1000;
  } else {
    const int64_t now = (ts.tv_sec * 1000000000LL + ts.tv_nsec) / 1000;
    const int64_t elapsed_time_since_last_write =
        now - out->last_write_time_us_;
    // frames_count = written_data / frame_size
    // play_time (ms) = frames_count / (sample_rate (Sec.) / 1000000)
    // sleep_time (ms) = play_time - elapsed_time
    int64_t sleep_time = bytes * 1000000LL /
                             audio_stream_out_frame_size(stream) /
                             out_get_sample_rate(&stream->common) -
                         elapsed_time_since_last_write;
    if (sleep_time > 0) {
      LOG(VERBOSE) << __func__ << ": sleep " << (sleep_time / 1000)
                   << " ms when writting FMQ datapath";
      lock.unlock();
      usleep(sleep_time);
      lock.lock();
    } else {
      // we don't sleep when we exit standby (this is typical for a real alsa
      // buffer).
      sleep_time = 0;
    }
    out->last_write_time_us_ = now + sleep_time;
  }
  return totalWritten;
}

static int out_get_render_position(const struct audio_stream_out* stream,
                                   uint32_t* dsp_frames) {
  if (dsp_frames == nullptr) return -EINVAL;

  const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
  // frames = (latency (ms) / 1000) * samples_per_second (sample_rate)
  const uint64_t latency_frames =
      (uint64_t)out_get_latency_ms(stream) * out->sample_rate_ / 1000;
  if (out->frames_rendered_ >= latency_frames) {
    *dsp_frames = (uint32_t)(out->frames_rendered_ - latency_frames);
  } else {
    *dsp_frames = 0;
  }

  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", dsp_frames=" << *dsp_frames;
  return 0;
}

static int out_add_audio_effect(const struct audio_stream* stream,
                                effect_handle_t effect) {
  const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", effect=" << effect;
  return 0;
}

static int out_remove_audio_effect(const struct audio_stream* stream,
                                   effect_handle_t effect) {
  const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", effect=" << effect;
  return 0;
}

static int out_get_next_write_timestamp(const struct audio_stream_out* stream,
                                        int64_t* timestamp) {
  const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
  *timestamp = 0;
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", timestamp=" << *timestamp;
  return -EINVAL;
}

static int out_pause(struct audio_stream_out* stream) {
  auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
  std::unique_lock<std::mutex> lock(out->mutex_);
  int retval = 0;
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", pausing (suspend)";
  if (out->bluetooth_output_.GetState() == BluetoothStreamState::STARTED) {
    out->frames_rendered_ = 0;
    retval = (out->bluetooth_output_.Suspend() ? 0 : -EIO);
  } else if (out->bluetooth_output_.GetState() ==
                 BluetoothStreamState::STARTING ||
             out->bluetooth_output_.GetState() ==
                 BluetoothStreamState::SUSPENDING) {
    LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                 << " NOT ready to pause?!";
    retval = -EBUSY;
  } else {
    LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << " paused already";
  }
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", pausing (suspend) retval=" << retval;

  return retval;
}

static int out_resume(struct audio_stream_out* stream) {
  auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
  std::unique_lock<std::mutex> lock(out->mutex_);
  int retval = 0;

  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", resuming (start)";
  if (out->bluetooth_output_.GetState() == BluetoothStreamState::STANDBY) {
    retval = (out->bluetooth_output_.Start() ? 0 : -EIO);
  } else if (out->bluetooth_output_.GetState() ==
                 BluetoothStreamState::STARTING ||
             out->bluetooth_output_.GetState() ==
                 BluetoothStreamState::SUSPENDING) {
    LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                 << " NOT ready to resume?!";
    retval = -EBUSY;
  } else if (out->bluetooth_output_.GetState() ==
             BluetoothStreamState::DISABLED) {
    LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
                 << " NOT allow to resume?!";
    retval = -EINVAL;
  } else {
    LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << " resumed already";
  }
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", resuming (start) retval=" << retval;

  return retval;
}

static int out_get_presentation_position(const struct audio_stream_out* stream,
                                         uint64_t* frames,
                                         struct timespec* timestamp) {
  if (frames == nullptr || timestamp == nullptr) {
    return -EINVAL;
  }

  const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
  out_calculate_feeding_delay_ms(out, nullptr, frames, timestamp);
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", frames=" << *frames << ", timestamp=" << timestamp->tv_sec
               << "." << StringPrintf("%09ld", timestamp->tv_nsec) << "s";
  return 0;
}

static void out_update_source_metadata(
    struct audio_stream_out* stream,
    const struct source_metadata* source_metadata) {
  auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
  std::unique_lock<std::mutex> lock(out->mutex_);
  if (source_metadata == nullptr || source_metadata->track_count == 0) {
    return;
  }
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", " << source_metadata->track_count << " track(s)";
  out->bluetooth_output_.UpdateMetadata(source_metadata);
}

static size_t samples_per_ticks(size_t milliseconds, uint32_t sample_rate,
                                size_t channel_count) {
  return milliseconds * sample_rate * channel_count / 1000;
}

int adev_open_output_stream(struct audio_hw_device* dev,
                            audio_io_handle_t handle, audio_devices_t devices,
                            audio_output_flags_t flags,
                            struct audio_config* config,
                            struct audio_stream_out** stream_out,
                            const char* address __unused) {
  *stream_out = nullptr;
  auto* out = new BluetoothStreamOut{};
  if (!out->bluetooth_output_.SetUp(devices)) {
    delete out;
    return -EINVAL;
  }
  LOG(VERBOSE) << __func__ << ": device=" << StringPrintf("%#x", devices);

  out->stream_out_.common.get_sample_rate = out_get_sample_rate;
  out->stream_out_.common.set_sample_rate = out_set_sample_rate;
  out->stream_out_.common.get_buffer_size = out_get_buffer_size;
  out->stream_out_.common.get_channels = out_get_channels;
  out->stream_out_.common.get_format = out_get_format;
  out->stream_out_.common.set_format = out_set_format;
  out->stream_out_.common.standby = out_standby;
  out->stream_out_.common.dump = out_dump;
  out->stream_out_.common.set_parameters = out_set_parameters;
  out->stream_out_.common.get_parameters = out_get_parameters;
  out->stream_out_.common.add_audio_effect = out_add_audio_effect;
  out->stream_out_.common.remove_audio_effect = out_remove_audio_effect;
  out->stream_out_.get_latency = out_get_latency_ms;
  out->stream_out_.set_volume = out_set_volume;
  out->stream_out_.write = out_write;
  out->stream_out_.get_render_position = out_get_render_position;
  out->stream_out_.get_next_write_timestamp = out_get_next_write_timestamp;
  out->stream_out_.pause = out_pause;
  out->stream_out_.resume = out_resume;
  out->stream_out_.get_presentation_position = out_get_presentation_position;
  out->stream_out_.update_source_metadata = out_update_source_metadata;

  if (!out->bluetooth_output_.LoadAudioConfig(config)) {
    LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << " failed to get audio config";
  }
  // WAR to support Mono / 16 bits per sample as the Bluetooth stack required
  if (config->channel_mask == AUDIO_CHANNEL_OUT_MONO && config->format == AUDIO_FORMAT_PCM_16_BIT) {
    LOG(INFO) << __func__ << ": force channels=" << StringPrintf("%#x", out->channel_mask_)
              << " to be AUDIO_CHANNEL_OUT_STEREO";
    out->bluetooth_output_.ForcePcmStereoToMono(true);
    config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
  }
  out->sample_rate_ = config->sample_rate;
  out->channel_mask_ = config->channel_mask;
  out->format_ = config->format;
  // frame is number of samples per channel
  out->frames_count_ =
      samples_per_ticks(kBluetoothDefaultOutputBufferMs, out->sample_rate_, 1);
  out->frames_rendered_ = 0;
  out->frames_presented_ = 0;

  {
    auto* bluetooth_device = reinterpret_cast<BluetoothAudioDevice*>(dev);
    std::lock_guard<std::mutex> guard(bluetooth_device->mutex_);
    bluetooth_device->opened_stream_outs_.push_back(out);
  }
  *stream_out = &out->stream_out_;
  LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState() << ", sample_rate=" << out->sample_rate_
            << ", channels=" << StringPrintf("%#x", out->channel_mask_) << ", format=" << out->format_
            << ", frames=" << out->frames_count_;
  return 0;
}

void adev_close_output_stream(struct audio_hw_device* dev,
                              struct audio_stream_out* stream) {
  auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", stopping";
  {
    auto* bluetooth_device = reinterpret_cast<BluetoothAudioDevice*>(dev);
    std::lock_guard<std::mutex> guard(bluetooth_device->mutex_);
    bluetooth_device->opened_stream_outs_.remove(out);
  }
  if (out->bluetooth_output_.GetState() != BluetoothStreamState::DISABLED) {
    out->frames_rendered_ = 0;
    out->frames_presented_ = 0;
    out->bluetooth_output_.Stop();
  }
  out->bluetooth_output_.TearDown();
  LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
               << ", stopped";
  delete out;
}

size_t adev_get_input_buffer_size(const struct audio_hw_device* dev,
                                  const struct audio_config* config) {
  /* TODO: Adjust this value */
  LOG(VERBOSE) << __func__;
  return 320;
}

static uint32_t in_get_sample_rate(const struct audio_stream* stream) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);

  return in->sample_rate_;
}

static int in_set_sample_rate(struct audio_stream* stream, uint32_t rate) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);

  LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
               << ", sample_rate=" << in->sample_rate_;
  return (rate == in->sample_rate_ ? 0 : -ENOSYS);
}

static size_t in_get_buffer_size(const struct audio_stream* stream) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  size_t buffer_size =
      in->frames_count_ * audio_stream_in_frame_size(&in->stream_in_);
  LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
               << ", buffer_size=" << buffer_size;
  return buffer_size;
}

static audio_channel_mask_t in_get_channels(const struct audio_stream* stream) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  audio_config_t audio_cfg;
  if (in->bluetooth_input_.LoadAudioConfig(&audio_cfg)) {
    LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
                 << " audio_cfg=" << audio_cfg;
    return audio_cfg.channel_mask;
  } else {
    LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_.GetState()
                 << ", channels=" << StringPrintf("%#x", in->channel_mask_)
                 << " failure";
    return in->channel_mask_;
  }
}

static audio_format_t in_get_format(const struct audio_stream* stream) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  audio_config_t audio_cfg;
  if (in->bluetooth_input_.LoadAudioConfig(&audio_cfg)) {
    LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
                 << " audio_cfg=" << audio_cfg;
    return audio_cfg.format;
  } else {
    LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_.GetState()
                 << ", format=" << in->format_ << " failure";
    return in->format_;
  }
}

static int in_set_format(struct audio_stream* stream, audio_format_t format) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
               << ", format=" << in->format_;
  return (format == in->format_ ? 0 : -ENOSYS);
}

static bool in_state_transition_timeout(BluetoothStreamIn* in,
                                        std::unique_lock<std::mutex>& lock,
                                        const BluetoothStreamState& state,
                                        uint16_t timeout_ms) {
  /* Don't loose suspend request, AF will not retry */
  while (in->bluetooth_input_.GetState() == state) {
    lock.unlock();
    usleep(1000);
    lock.lock();

    /* Don't block AF forever */
    if (--timeout_ms <= 0) {
      LOG(WARNING) << __func__ << ", can't suspend - stucked in: "
                   << static_cast<int>(state) << " state";
      return false;
    }
  }

  return true;
}

static int in_standby(struct audio_stream* stream) {
  auto* in = reinterpret_cast<BluetoothStreamIn*>(stream);
  std::unique_lock<std::mutex> lock(in->mutex_);
  int retval = 0;

  LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
               << " being standby (suspend)";

  /* Give some time to start up */
  if (!in_state_transition_timeout(in, lock, BluetoothStreamState::STARTING,
                                   kBluetoothDefaultInputStateTimeoutMs)) {
    LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
               << " NOT ready to by standby";
    return retval;
  }

  if (in->bluetooth_input_.GetState() == BluetoothStreamState::STARTED) {
    retval = (in->bluetooth_input_.Suspend() ? 0 : -EIO);
  } else if (in->bluetooth_input_.GetState() !=
             BluetoothStreamState::SUSPENDING) {
    LOG(DEBUG) << __func__ << ": state=" << in->bluetooth_input_.GetState()
               << " standby already";
    return retval;
  }

  /* Give some time to suspend */
  if (!in_state_transition_timeout(in, lock, BluetoothStreamState::SUSPENDING,
                                   kBluetoothDefaultInputStateTimeoutMs)) {
    LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
               << " NOT ready to by standby";
    return 0;
  }

  LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
               << " standby (suspend) retval=" << retval;

  return retval;
}

static int in_dump(const struct audio_stream* stream, int fd) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState();

  return 0;
}

static int in_set_parameters(struct audio_stream* stream, const char* kvpairs) {
  auto* in = reinterpret_cast<BluetoothStreamIn*>(stream);
  std::unique_lock<std::mutex> lock(in->mutex_);
  int retval = 0;

  LOG(INFO) << __func__
            << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState()
            << ", kvpairs=[" << kvpairs << "]";

  std::unordered_map<std::string, std::string> params =
      ParseAudioParams(kvpairs);

  if (params.empty()) return retval;

  LOG(INFO) << __func__ << ": ParamsMap=[" << GetAudioParamString(params)
            << "]";

  return retval;
}

static char* in_get_parameters(const struct audio_stream* stream,
                               const char* keys) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  std::unique_lock<std::mutex> lock(in->mutex_);

  LOG(VERBOSE) << __func__
               << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState()
               << ", keys=[" << keys << "]";

  std::unordered_map<std::string, std::string> params = ParseAudioParams(keys);
  if (params.empty()) return strdup("");

  audio_config_t audio_cfg;
  if (in->bluetooth_input_.LoadAudioConfig(&audio_cfg)) {
    LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
                 << " audio_cfg=" << audio_cfg;
  } else {
    LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
               << " failed to get audio config";
  }

  std::unordered_map<std::string, std::string> return_params;

  /* TODO: Implement parameter getter */

  std::string result;
  for (const auto& ptr : return_params) {
    result += ptr.first + "=" + ptr.second + ";";
  }

  return strdup(result.c_str());
}

static int in_add_audio_effect(const struct audio_stream* stream,
                               effect_handle_t effect) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
               << ", effect=" << effect;
  return 0;
}

static int in_remove_audio_effect(const struct audio_stream* stream,
                                  effect_handle_t effect) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
               << ", effect=" << effect;
  return 0;
}

static int in_set_gain(struct audio_stream_in* stream, float gain) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  LOG(VERBOSE) << __func__
               << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();

  return 0;
}

static ssize_t in_read(struct audio_stream_in* stream, void* buffer,
                       size_t bytes) {
  auto* in = reinterpret_cast<BluetoothStreamIn*>(stream);
  std::unique_lock<std::mutex> lock(in->mutex_);
  size_t totalRead = 0;

  /* Give some time to start up */
  if (!in_state_transition_timeout(in, lock, BluetoothStreamState::STARTING,
                                   kBluetoothDefaultInputStateTimeoutMs))
    return -EBUSY;

  if (in->bluetooth_input_.GetState() != BluetoothStreamState::STARTED) {
    LOG(INFO) << __func__ << ": state=" << in->bluetooth_input_.GetState()
              << " first time bytes=" << bytes;

    int retval = 0;
    LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
                 << ", starting";
    if (in->bluetooth_input_.GetState() == BluetoothStreamState::STANDBY) {
      retval = (in->bluetooth_input_.Start() ? 0 : -EIO);
    } else if (in->bluetooth_input_.GetState() ==
               BluetoothStreamState::SUSPENDING) {
      LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_.GetState()
                   << " NOT ready to start?!";
      retval = -EBUSY;
    } else if (in->bluetooth_input_.GetState() ==
               BluetoothStreamState::DISABLED) {
      LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_.GetState()
                   << " NOT allow to start?!";
      retval = -EINVAL;
    } else {
      LOG(DEBUG) << __func__ << ": state=" << in->bluetooth_input_.GetState()
                 << " started already";
    }
    LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
                 << ", starting (start) retval=" << retval;

    if (retval) {
      LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
                 << " failed to start";
      return retval;
    }
  }

  lock.unlock();
  totalRead = in->bluetooth_input_.ReadData(buffer, bytes);
  lock.lock();

  struct timespec ts = {.tv_sec = 0, .tv_nsec = 0};
  clock_gettime(CLOCK_MONOTONIC, &ts);
  in->last_read_time_us_ = (ts.tv_sec * 1000000000LL + ts.tv_nsec) / 1000;

  const size_t frames = totalRead / audio_stream_in_frame_size(stream);
  in->frames_presented_ += frames;

  return totalRead;
}

static uint32_t in_get_input_frames_lost(struct audio_stream_in* stream) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  LOG(VERBOSE) << __func__
               << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();

  return 0;
}

static int in_get_capture_position(const struct audio_stream_in* stream,
                                   int64_t* frames, int64_t* time) {
  if (stream == NULL || frames == NULL || time == NULL) {
    return -EINVAL;
  }
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);

  if (in->bluetooth_input_.GetState() == BluetoothStreamState::STANDBY) {
    LOG(WARNING) << __func__ << ": state= " << in->bluetooth_input_.GetState();
    return -ENOSYS;
  }

  in_calculate_starving_delay_ms(in, frames, time);

  return 0;
}

static int in_start(const struct audio_stream_in* stream) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  LOG(VERBOSE) << __func__
               << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();

  return 0;
}

static int in_stop(const struct audio_stream_in* stream) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  LOG(VERBOSE) << __func__
               << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();

  return 0;
}

static int in_create_mmap_buffer(const struct audio_stream_in* stream,
                                 int32_t min_size_frames,
                                 struct audio_mmap_buffer_info* info) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  LOG(VERBOSE) << __func__
               << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();

  return -ENOSYS;
}

static int in_get_mmap_position(const struct audio_stream_in* stream,
                                struct audio_mmap_position* position) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  LOG(VERBOSE) << __func__
               << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();

  return -ENOSYS;
}

static int in_get_active_microphones(
    const struct audio_stream_in* stream,
    struct audio_microphone_characteristic_t* mic_array, size_t* mic_count) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  LOG(VERBOSE) << __func__
               << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();

  return -ENOSYS;
}

static int in_set_microphone_direction(const struct audio_stream_in* stream,
                                       audio_microphone_direction_t direction) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  LOG(VERBOSE) << __func__
               << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();

  return -ENOSYS;
}

static int in_set_microphone_field_dimension(
    const struct audio_stream_in* stream, float zoom) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  LOG(VERBOSE) << __func__
               << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();

  return -ENOSYS;
}

static void in_update_sink_metadata(struct audio_stream_in* stream,
                                    const struct sink_metadata* sink_metadata) {
  const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
  LOG(VERBOSE) << __func__
               << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
}

int adev_open_input_stream(struct audio_hw_device* dev,
                           audio_io_handle_t handle, audio_devices_t devices,
                           struct audio_config* config,
                           struct audio_stream_in** stream_in,
                           audio_input_flags_t flags __unused,
                           const char* address __unused,
                           audio_source_t source __unused) {
  *stream_in = nullptr;
  auto* in = new BluetoothStreamIn{};
  if (!in->bluetooth_input_.SetUp(devices)) {
    delete in;
    return -EINVAL;
  }

  LOG(INFO) << __func__ << ": device=" << StringPrintf("%#x", devices);

  in->stream_in_.common.get_sample_rate = in_get_sample_rate;
  in->stream_in_.common.set_sample_rate = in_set_sample_rate;
  in->stream_in_.common.get_buffer_size = in_get_buffer_size;
  in->stream_in_.common.get_channels = in_get_channels;
  in->stream_in_.common.get_format = in_get_format;
  in->stream_in_.common.set_format = in_set_format;
  in->stream_in_.common.standby = in_standby;
  in->stream_in_.common.dump = in_dump;
  in->stream_in_.common.set_parameters = in_set_parameters;
  in->stream_in_.common.get_parameters = in_get_parameters;
  in->stream_in_.common.add_audio_effect = in_add_audio_effect;
  in->stream_in_.common.remove_audio_effect = in_remove_audio_effect;
  in->stream_in_.set_gain = in_set_gain;
  in->stream_in_.read = in_read;
  in->stream_in_.get_input_frames_lost = in_get_input_frames_lost;
  in->stream_in_.get_capture_position = in_get_capture_position;
  in->stream_in_.start = in_start;
  in->stream_in_.stop = in_stop;
  in->stream_in_.create_mmap_buffer = in_create_mmap_buffer;
  in->stream_in_.get_mmap_position = in_get_mmap_position;
  in->stream_in_.get_active_microphones = in_get_active_microphones;
  in->stream_in_.set_microphone_direction = in_set_microphone_direction;
  in->stream_in_.set_microphone_field_dimension =
      in_set_microphone_field_dimension;
  in->stream_in_.update_sink_metadata = in_update_sink_metadata;

  if (!in->bluetooth_input_.LoadAudioConfig(config)) {
    LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
               << " failed to get audio config";
    return -EINVAL;
  }

  in->sample_rate_ = config->sample_rate;
  in->channel_mask_ = config->channel_mask;
  in->format_ = config->format;
  // frame is number of samples per channel
  in->frames_count_ =
      samples_per_ticks(kBluetoothDefaultInputBufferMs, in->sample_rate_, 1);
  in->frames_presented_ = 0;

  *stream_in = &in->stream_in_;
  LOG(INFO) << __func__ << ": state=" << in->bluetooth_input_.GetState()
            << ", sample_rate=" << in->sample_rate_
            << ", channels=" << StringPrintf("%#x", in->channel_mask_)
            << ", format=" << in->format_ << ", frames=" << in->frames_count_;

  return 0;
}

void adev_close_input_stream(struct audio_hw_device* dev,
                             struct audio_stream_in* stream) {
  auto* in = reinterpret_cast<BluetoothStreamIn*>(stream);

  if (in->bluetooth_input_.GetState() != BluetoothStreamState::DISABLED) {
    in->bluetooth_input_.Stop();
  }

  in->bluetooth_input_.TearDown();
  LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
               << ", stopped";

  delete in;
}
