// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/renderer/media/renderer_webaudiodevice_impl.h"

#include <memory>

#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "media/audio/audio_features.h"
#include "media/base/audio_capturer_source.h"
#include "media/base/audio_glitch_info.h"
#include "media/base/limits.h"
#include "media/base/mock_audio_renderer_sink.h"
#include "media/base/output_device_info.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/tokens/tokens.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/web/modules/media/audio/audio_device_factory.h"

namespace content {

namespace {

using ::media::limits::kMaxWebAudioBufferSize;
using ::media::limits::kMinWebAudioBufferSize;
using ::testing::_;
using ::testing::InSequence;

class MockAudioRendererSink : public media::AudioRendererSink {
 public:
  explicit MockAudioRendererSink() = default;
  void Initialize(const media::AudioParameters& params,
                  media::AudioRendererSink::RenderCallback* callback) override {
    callback_ = callback;
  }
  MOCK_METHOD(void, Start, (), (override));
  MOCK_METHOD(void, Stop, (), (override));
  MOCK_METHOD(void, Pause, (), (override));
  MOCK_METHOD(void, Play, (), (override));
  MOCK_METHOD(void, Flush, (), (override));
  MOCK_METHOD(bool, SetVolume, (double volume), (override));
  MOCK_METHOD(media::OutputDeviceInfo, GetOutputDeviceInfo, (), (override));
  MOCK_METHOD(void,
              GetOutputDeviceInfoAsync,
              (OutputDeviceInfoCB info_cb),
              (override));
  MOCK_METHOD(bool, IsOptimizedForHardwareParameters, (), (override));
  MOCK_METHOD(bool, CurrentThreadIsRenderingThread, (), (override));

  raw_ptr<media::AudioRendererSink::RenderCallback, DanglingUntriaged>
      callback_ = nullptr;

 private:
  ~MockAudioRendererSink() override = default;
};

constexpr int kHardwareSampleRate = 44100;
constexpr int kHardwareBufferSize = 128;
const blink::LocalFrameToken kFrameToken;
const media::OutputDeviceInfo kHealthyDevice(
    media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK);
const media::OutputDeviceInfo kErrorDevice(
    media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL);

media::AudioParameters MockGetOutputDeviceParameters(
    const blink::LocalFrameToken& frame_token,
    const std::string& device_id) {
  return media::AudioParameters(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
                                media::ChannelLayoutConfig::Stereo(),
                                kHardwareSampleRate, kHardwareBufferSize);
}

class RendererWebAudioDeviceImplUnderTest : public RendererWebAudioDeviceImpl {
 public:
  RendererWebAudioDeviceImplUnderTest(
      const blink::WebAudioSinkDescriptor& sink_descriptor,
      media::ChannelLayoutConfig layout_config,
      const blink::WebAudioLatencyHint& latency_hint,
      std::optional<float> context_sample_rate,
      media::AudioRendererSink::RenderCallback* callback,
      CreateSilentSinkCallback silent_sink_callback)
      : RendererWebAudioDeviceImpl(
            sink_descriptor,
            layout_config,
            latency_hint,
            context_sample_rate,
            callback,
            base::BindOnce(&MockGetOutputDeviceParameters),
            std::move(silent_sink_callback)) {}
};
class RendererWebAudioDeviceImplConstructorParamTest
    : public RendererWebAudioDeviceImpl {
 public:
  RendererWebAudioDeviceImplConstructorParamTest(
      const blink::WebAudioSinkDescriptor& sink_descriptor,
      media::ChannelLayoutConfig layout_config,
      const blink::WebAudioLatencyHint& latency_hint,
      std::optional<float> context_sample_rate,
      media::AudioRendererSink::RenderCallback* callback,
      CreateSilentSinkCallback silent_sink_callback,
      base::RepeatingCallback<
          media::AudioParameters(const blink::LocalFrameToken&,
                                 const std::string&)> device_params_cb);
};

RendererWebAudioDeviceImplConstructorParamTest::
    RendererWebAudioDeviceImplConstructorParamTest(
        const blink::WebAudioSinkDescriptor& sink_descriptor,
        media::ChannelLayoutConfig layout_config,
        const blink::WebAudioLatencyHint& latency_hint,
        std::optional<float> context_sample_rate,
        media::AudioRendererSink::RenderCallback* callback,
        CreateSilentSinkCallback silent_sink_callback,
        base::RepeatingCallback<
            media::AudioParameters(const blink::LocalFrameToken&,
                                   const std::string&)> device_params_cb)
    : RendererWebAudioDeviceImpl(sink_descriptor,
                                 layout_config,
                                 latency_hint,
                                 context_sample_rate,
                                 callback,
                                 std::move(device_params_cb),
                                 std::move(silent_sink_callback)) {}

}  // namespace

class RendererWebAudioDeviceImplTest
    : public media::AudioRendererSink::RenderCallback,
      public blink::AudioDeviceFactory,
      public testing::Test {
 public:
  MOCK_METHOD(int,
              Render,
              (base::TimeDelta delay,
               base::TimeTicks delay_timestamp,
               const media::AudioGlitchInfo& glitch_info,
               media::AudioBus* dest),
              (override));

  void OnRenderError() override {}

  scoped_refptr<media::AudioRendererSink> CreateMockSilentSink(
      const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
    return mock_audio_renderer_sink_;
  }

 protected:
  RendererWebAudioDeviceImplTest() {
    mock_audio_renderer_sink_ = base::MakeRefCounted<MockAudioRendererSink>();
  }


  void SetupDevice(blink::WebAudioLatencyHint latencyHint) {
    blink::WebAudioSinkDescriptor sink_descriptor(
        blink::WebString::FromUTF8(std::string()), kFrameToken);
    webaudio_device_ = std::make_unique<RendererWebAudioDeviceImplUnderTest>(
        sink_descriptor, media::ChannelLayoutConfig::Mono(), latencyHint,
        context_sample_rate_, this,
        base::BindRepeating(
            &RendererWebAudioDeviceImplTest::CreateMockSilentSink,
            // Guaranteed to be valid because |this| owns |webaudio_device_| and
            // so will outlive it.
            base::Unretained(this)));
    webaudio_device_->SetSilentSinkTaskRunnerForTesting(
        blink::scheduler::GetSingleThreadTaskRunnerForTesting());
  }

  void SetupDevice(media::ChannelLayoutConfig layout_config) {
    blink::WebAudioSinkDescriptor sink_descriptor(
        blink::WebString::FromUTF8(std::string()), kFrameToken);
    webaudio_device_ = std::make_unique<RendererWebAudioDeviceImplUnderTest>(
        sink_descriptor, layout_config,
        blink::WebAudioLatencyHint(
            blink::WebAudioLatencyHint::kCategoryInteractive),
        context_sample_rate_, this,
        base::BindRepeating(
            &RendererWebAudioDeviceImplTest::CreateMockSilentSink,
            // Guaranteed to be valid because |this| owns |webaudio_device_| and
            // so will outlive it.
            base::Unretained(this)));
    webaudio_device_->SetSilentSinkTaskRunnerForTesting(
        blink::scheduler::GetSingleThreadTaskRunnerForTesting());
  }

  void SetupDevice(blink::WebAudioSinkDescriptor sink_descriptor) {
    webaudio_device_ = std::make_unique<RendererWebAudioDeviceImplUnderTest>(
        sink_descriptor, media::ChannelLayoutConfig::Mono(),
        blink::WebAudioLatencyHint(
            blink::WebAudioLatencyHint::kCategoryInteractive),
        context_sample_rate_, this,
        base::BindRepeating(
            &RendererWebAudioDeviceImplTest::CreateMockSilentSink,
            // Guaranteed to be valid because |this| owns |webaudio_device_| and
            // so will outlive it.
            base::Unretained(this)));
    webaudio_device_->SetSilentSinkTaskRunnerForTesting(
        blink::scheduler::GetSingleThreadTaskRunnerForTesting());
  }

  scoped_refptr<media::AudioRendererSink> NewAudioRendererSink(
      blink::WebAudioDeviceSourceType render_token,
      const blink::LocalFrameToken& frame_token,
      const media::AudioSinkParameters& params) override {
    return mock_audio_renderer_sink_;
  }

  void TearDown() override { webaudio_device_.reset(); }

  std::unique_ptr<RendererWebAudioDeviceImpl> webaudio_device_;
  base::test::SingleThreadTaskEnvironment task_environment_;
  scoped_refptr<MockAudioRendererSink> mock_audio_renderer_sink_;
  std::optional<float> context_sample_rate_;
};

class RendererWebAudioDeviceImplBufferSizeTest : public ::testing::Test {
 protected:
  static constexpr int kHardwareSampleRate48k = 48000;
  static constexpr int kHardwareBufferSize48k = 480;
  static constexpr int kHardwareSampleRate44k = 44100;
  static constexpr int kHardwareBufferSize44k = 441;
  base::test::ScopedFeatureList feature_list_;
};

// When the kWebAudioRemoveAudioDestinationResampler
// feature is disabled, the GetOutputBufferSize method returns the default
// hardware buffer size, regardless of the context sample rate.
TEST_F(RendererWebAudioDeviceImplBufferSizeTest,
       InteractiveLatency_FeatureDisabled_UsesDefaultBufferSize) {
  feature_list_.InitAndDisableFeature(
      features::kWebAudioRemoveAudioDestinationResampler);
  blink::WebAudioLatencyHint latency_hint(
      blink::WebAudioLatencyHint::kCategoryInteractive);
  media::AudioParameters hardware_params(
      media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
      media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate48k,
      kHardwareBufferSize48k);

  // When feature is disabled, we ensure the context_sample_rate is using
  // default hardware sample rate before calling
  // `RendererWebAudioDeviceImpl::GetOutputBufferSize`.
  int context_sample_rate = kHardwareSampleRate48k;
  int output_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize(
      latency_hint, context_sample_rate, hardware_params);
  EXPECT_EQ(output_buffer_size, 480);
}

// When the kWebAudioRemoveAudioDestinationResampler
// feature is enabled and the context sample rate matches the hardware sample
// rate, the GetOutputBufferSize method returns the default hardware buffer
// size.
TEST_F(RendererWebAudioDeviceImplBufferSizeTest,
       InteractiveLatency_SameSampleRate_ReturnsDefaultBufferSize) {
  feature_list_.InitAndEnableFeature(
      features::kWebAudioRemoveAudioDestinationResampler);
  blink::WebAudioLatencyHint latency_hint(
      blink::WebAudioLatencyHint::kCategoryInteractive);
  media::AudioParameters hardware_params(
      media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
      media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate48k,
      kHardwareBufferSize48k);

  int context_sample_rate = 48000;
  int output_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize(
      latency_hint, context_sample_rate, hardware_params);
  EXPECT_EQ(output_buffer_size, 480);
}

// When the kWebAudioRemoveAudioDestinationResampler
// feature is enabled and the context sample rate is significantly lower than
// the hardware sample rate, the GetOutputBufferSize method returns the minimum
// allowed buffer size (kMinWebAudioBufferSize). This ensures that the scaled
// buffer size is capped at the minimum.
TEST_F(RendererWebAudioDeviceImplBufferSizeTest,
       InteractiveLatency_LowSampleRate_CapsAtMinBufferSize) {
  feature_list_.InitAndEnableFeature(
      features::kWebAudioRemoveAudioDestinationResampler);
  blink::WebAudioLatencyHint latency_hint(
      blink::WebAudioLatencyHint::kCategoryInteractive);
  media::AudioParameters hardware_params(
      media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
      media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate48k,
      kHardwareBufferSize48k);

  int context_sample_rate = 8000;
  int output_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize(
      latency_hint, context_sample_rate, hardware_params);
  EXPECT_EQ(output_buffer_size, kMinWebAudioBufferSize);
}

// When the kWebAudioRemoveAudioDestinationResampler
// feature is enabled and the context sample rate is higher than the hardware
// sample rate, the GetOutputBufferSize method correctly scales the buffer size.
TEST_F(RendererWebAudioDeviceImplBufferSizeTest,
       InteractiveLatency_HighSampleRate_ScalesBufferSize) {
  feature_list_.InitAndEnableFeature(
      features::kWebAudioRemoveAudioDestinationResampler);
  blink::WebAudioLatencyHint latency_hint(
      blink::WebAudioLatencyHint::kCategoryInteractive);
  media::AudioParameters hardware_params(
      media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
      media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate48k,
      kHardwareBufferSize48k);

  int context_sample_rate = 768000;
  int output_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize(
      latency_hint, context_sample_rate, hardware_params);
  EXPECT_EQ(output_buffer_size, 7680);
}

// When the kWebAudioRemoveAudioDestinationResampler feature is enabled and the
// context sample rate is slightly higher than the hardware sample rate, the
// GetOutputBufferSize method correctly scales the buffer size, demonstrating
// accurate rounding behavior.
TEST_F(RendererWebAudioDeviceImplBufferSizeTest,
       InteractiveLatency_CloseSampleRate_ScalesBufferSize) {
  feature_list_.InitAndEnableFeature(
      features::kWebAudioRemoveAudioDestinationResampler);
  blink::WebAudioLatencyHint latency_hint(
      blink::WebAudioLatencyHint::kCategoryInteractive);
  media::AudioParameters hardware_params(
      media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
      media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate48k,
      kHardwareBufferSize48k);

  int context_sample_rate = 48001;
  int output_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize(
      latency_hint, context_sample_rate, hardware_params);
  EXPECT_EQ(output_buffer_size, 481);
}

// When the kWebAudioRemoveAudioDestinationResampler feature is enabled and the
// context sample rate is slightly higher than the hardware sample rate, with
// different hardware parameters, the GetOutputBufferSize method correctly
// scales the buffer size, demonstrating general rounding and scaling behavior
// with various hardware configurations.
TEST_F(RendererWebAudioDeviceImplBufferSizeTest,
       InteractiveLatency_CloseSampleRate2_ScalesBufferSize) {
  feature_list_.InitAndEnableFeature(
      features::kWebAudioRemoveAudioDestinationResampler);
  blink::WebAudioLatencyHint latency_hint(
      blink::WebAudioLatencyHint::kCategoryInteractive);
  media::AudioParameters hardware_params(
      media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
      media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate44k,
      kHardwareBufferSize44k);

  int context_sample_rate = 48000;
  int output_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize(
      latency_hint, context_sample_rate, hardware_params);
  EXPECT_EQ(output_buffer_size, 481);
}

// When the kWebAudioRemoveAudioDestinationResampler
// feature is enabled and the context sample rate is extremely high (potentially
// unsupported), the GetOutputBufferSize method caps the scaled buffer size at
// the maximum allowed buffer size (kMaxWebAudioBufferSize).
TEST_F(RendererWebAudioDeviceImplBufferSizeTest,
       InteractiveLatency_VeryHighSampleRate_CapsAtMaxBufferSize) {
  feature_list_.InitAndEnableFeature(
      features::kWebAudioRemoveAudioDestinationResampler);
  blink::WebAudioLatencyHint latency_hint(
      blink::WebAudioLatencyHint::kCategoryInteractive);
  media::AudioParameters hardware_params(
      media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
      media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate48k,
      kHardwareBufferSize48k);

  int context_sample_rate = 999000;
  int output_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize(
      latency_hint, context_sample_rate, hardware_params);
  EXPECT_EQ(output_buffer_size, kMaxWebAudioBufferSize);
}

TEST_F(RendererWebAudioDeviceImplTest, ChannelLayout) {
  for (int ch = 1; ch < static_cast<int>(media::limits::kMaxChannels); ++ch) {
    SCOPED_TRACE(base::StringPrintf("ch == %d", ch));

    media::ChannelLayout layout = media::GuessChannelLayout(ch);
    if (layout == media::CHANNEL_LAYOUT_UNSUPPORTED) {
      layout = media::CHANNEL_LAYOUT_DISCRETE;
    }

    SetupDevice({layout, ch});
    media::AudioParameters sink_params =
        webaudio_device_->get_sink_params_for_testing();
    EXPECT_TRUE(sink_params.IsValid());
    EXPECT_EQ(layout, sink_params.channel_layout());
    EXPECT_EQ(ch, sink_params.channels());
  }
}

TEST_F(RendererWebAudioDeviceImplTest, NullSink_RenderWorks) {
  {
    InSequence s;

    EXPECT_CALL(*mock_audio_renderer_sink_, Start).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Play).Times(1);
    EXPECT_CALL(*this, Render).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Stop).Times(1);
  }

  // The WebAudioSinkDescriptor constructor with frame token will construct a
  // silent sink.
  SetupDevice(blink::WebAudioSinkDescriptor(kFrameToken));
  webaudio_device_->Start();
  mock_audio_renderer_sink_->callback_->Render(
      base::TimeDelta::Min(), base::TimeTicks::Now(), {},
      media::AudioBus::Create(1, kHardwareBufferSize).get());
  webaudio_device_->Stop();
}

TEST_F(RendererWebAudioDeviceImplTest, NullSink_PauseResumeWorks) {
  {
    InSequence s;

    EXPECT_CALL(*mock_audio_renderer_sink_, Start).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Play).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Pause).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Play).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Stop).Times(1);
  }

  // The WebAudioSinkDescriptor constructor with frame token will construct a
  // silent sink.
  SetupDevice(blink::WebAudioSinkDescriptor(kFrameToken));
  webaudio_device_->Start();
  webaudio_device_->Pause();
  webaudio_device_->Resume();
  webaudio_device_->Stop();
}

TEST_F(RendererWebAudioDeviceImplTest,
       NullSink_StartRenderStopStartRenderStopWorks) {
  {
    InSequence s;

    EXPECT_CALL(*mock_audio_renderer_sink_, Start).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Play).Times(1);
    EXPECT_CALL(*this, Render).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Stop).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Start).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Play).Times(1);
    EXPECT_CALL(*this, Render).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Stop).Times(1);
  }

  // The WebAudioSinkDescriptor constructor with frame token will construct a
  // silent sink.
  SetupDevice(blink::WebAudioSinkDescriptor(kFrameToken));
  webaudio_device_->Start();
  mock_audio_renderer_sink_->callback_->Render(
      base::TimeDelta::Min(), base::TimeTicks::Now(), {},
      media::AudioBus::Create(1, kHardwareBufferSize).get());
  webaudio_device_->Stop();
  webaudio_device_->Start();
  mock_audio_renderer_sink_->callback_->Render(
      base::TimeDelta::Min(), base::TimeTicks::Now(), {},
      media::AudioBus::Create(1, kHardwareBufferSize).get());
  webaudio_device_->Stop();
}

TEST_F(RendererWebAudioDeviceImplTest, NullSink_RepeatedStartWorks) {
  {
    InSequence s;

    EXPECT_CALL(*mock_audio_renderer_sink_, Start).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Play).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Stop).Times(1);
  }

  // The WebAudioSinkDescriptor constructor with frame token will construct a
  // silent sink.
  SetupDevice(blink::WebAudioSinkDescriptor(kFrameToken));
  webaudio_device_->Start();
  webaudio_device_->Start();
  webaudio_device_->Stop();
}

TEST_F(RendererWebAudioDeviceImplTest, NullSink_RepeatedPauseWorks) {
  {
    InSequence s;

    EXPECT_CALL(*mock_audio_renderer_sink_, Start).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Play).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Pause).Times(2);
    EXPECT_CALL(*mock_audio_renderer_sink_, Stop).Times(1);
  }

  // The WebAudioSinkDescriptor constructor with frame token will construct a
  // silent sink.
  SetupDevice(blink::WebAudioSinkDescriptor(kFrameToken));
  webaudio_device_->Start();
  webaudio_device_->Pause();
  webaudio_device_->Pause();
  webaudio_device_->Stop();
}

TEST_F(RendererWebAudioDeviceImplTest, NullSink_RepeatedResumeWorks) {
  {
    InSequence s;

    EXPECT_CALL(*mock_audio_renderer_sink_, Start).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Play).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Pause).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Play).Times(2);
    EXPECT_CALL(*mock_audio_renderer_sink_, Stop).Times(1);
  }

  // The WebAudioSinkDescriptor constructor with frame token will construct a
  // silent sink.
  SetupDevice(blink::WebAudioSinkDescriptor(kFrameToken));
  webaudio_device_->Start();
  webaudio_device_->Pause();
  webaudio_device_->Resume();
  webaudio_device_->Resume();
  webaudio_device_->Stop();
}

TEST_F(RendererWebAudioDeviceImplTest, NullSink_RepeatedStopWorks) {
  {
    InSequence s;

    EXPECT_CALL(*mock_audio_renderer_sink_, Start).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Play).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Stop).Times(1);
  }

  // The WebAudioSinkDescriptor constructor with frame token will construct a
  // silent sink.
  SetupDevice(blink::WebAudioSinkDescriptor(kFrameToken));
  webaudio_device_->Start();
  webaudio_device_->Stop();
  webaudio_device_->Stop();
}

TEST_F(RendererWebAudioDeviceImplTest,
       CreateSinkAndGetDeviceStatus_HealthyDevice) {
  {
    InSequence s;

    EXPECT_CALL(*mock_audio_renderer_sink_, GetOutputDeviceInfo)
        .Times(1)
        .WillOnce(testing::Return(kHealthyDevice));
    EXPECT_CALL(*mock_audio_renderer_sink_, Start).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Play).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Stop).Times(1);
  }

  SetupDevice(media::ChannelLayoutConfig::Stereo());

  // `sink_` should be created after OUTPUT_DEVICE_STATUS_OK status return from
  // `CreateAndGetSinkStatus` call.
  EXPECT_EQ(webaudio_device_->sink_, nullptr);
  media::OutputDeviceStatus status =
      webaudio_device_->MaybeCreateSinkAndGetStatus();
  EXPECT_NE(webaudio_device_->sink_, nullptr);

  // Healthy device should return OUTPUT_DEVICE_STATUS_OK.
  EXPECT_EQ(status, media ::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK);
  webaudio_device_->Start();
  webaudio_device_->Stop();
}

TEST_F(RendererWebAudioDeviceImplTest,
       CreateSinkAndGetDeviceStatus_ErrorDevice) {
  {
    InSequence s;

    EXPECT_CALL(*mock_audio_renderer_sink_, GetOutputDeviceInfo)
        .Times(1)
        .WillOnce(testing::Return(kErrorDevice));
    EXPECT_CALL(*mock_audio_renderer_sink_, Start).Times(0);
    EXPECT_CALL(*mock_audio_renderer_sink_, Play).Times(0);
    // Stop() is necessary before destruction per AudioRendererSink contract.
    EXPECT_CALL(*mock_audio_renderer_sink_, Stop).Times(1);
  }

  SetupDevice(media::ChannelLayoutConfig::Stereo());

  // `sink_` should be remain as nullptr after
  // OUTPUT_DEVICE_STATUS_ERROR_INTERNAL status return from
  // `CreateAndGetSinkStatus` call.
  EXPECT_EQ(webaudio_device_->sink_, nullptr);
  media::OutputDeviceStatus status =
      webaudio_device_->MaybeCreateSinkAndGetStatus();
  EXPECT_EQ(webaudio_device_->sink_, nullptr);

  // Error device should return OUTPUT_DEVICE_STATUS_ERROR_INTERNAL.
  EXPECT_EQ(status,
            media ::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL);
}

TEST_F(RendererWebAudioDeviceImplTest,
       CreateSinkAndGetDeviceStatus_SilentSink) {
  {
    InSequence s;

    // Silent sink shouldn't invoke `GetOutputDeviceInfo`.
    EXPECT_CALL(*mock_audio_renderer_sink_, GetOutputDeviceInfo).Times(0);
    EXPECT_CALL(*mock_audio_renderer_sink_, Start).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Play).Times(1);
    EXPECT_CALL(*mock_audio_renderer_sink_, Stop).Times(1);
  }

  // The WebAudioSinkDescriptor constructor with frame token will construct a
  // silent sink.
  SetupDevice(blink::WebAudioSinkDescriptor(kFrameToken));

  // `sink_` should be created after OUTPUT_DEVICE_STATUS_OK status return from
  // `CreateAndGetSinkStatus` call.
  EXPECT_EQ(webaudio_device_->sink_, nullptr);
  media::OutputDeviceStatus status =
      webaudio_device_->MaybeCreateSinkAndGetStatus();
  EXPECT_NE(webaudio_device_->sink_, nullptr);

  // Silent sink should return OUTPUT_DEVICE_STATUS_OK.
  EXPECT_EQ(status, media ::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK);
  webaudio_device_->Start();
  webaudio_device_->Stop();
}

TEST_F(RendererWebAudioDeviceImplTest, ValidDeviceParameters) {
  // Setup a scenario where the device parameters callback returns valid
  // parameters.
  SetupDevice(media::ChannelLayoutConfig::Stereo());

  EXPECT_EQ(webaudio_device_->GetOriginalSinkParamsForTesting().sample_rate(),
            kHardwareSampleRate);
  EXPECT_EQ(
      webaudio_device_->GetOriginalSinkParamsForTesting().frames_per_buffer(),
      kHardwareBufferSize);
  EXPECT_TRUE(webaudio_device_->GetOriginalSinkParamsForTesting().IsValid());
}

TEST_F(RendererWebAudioDeviceImplTest,
       HandleInvalidOriginalSinkParamsInConstructor) {
  media::AudioParameters default_params;
  EXPECT_FALSE(default_params.IsValid());
  // Test for handling invalid original sink parameters in constructor.
  auto mock_device_params_cb =
      base::BindRepeating([](const blink::LocalFrameToken&,
                             const std::string&) -> media::AudioParameters {
        return media::AudioParameters();
      });
  blink::WebAudioSinkDescriptor sink_descriptor(
      blink::WebString::FromUTF8(std::string()), kFrameToken);

  RendererWebAudioDeviceImplConstructorParamTest device_under_test(
      sink_descriptor, media::ChannelLayoutConfig::Stereo(),
      blink::WebAudioLatencyHint(
          blink::WebAudioLatencyHint::kCategoryInteractive),
      std::nullopt, this,
      base::BindRepeating(&RendererWebAudioDeviceImplTest::CreateMockSilentSink,
                          base::Unretained(this)),
      mock_device_params_cb);

  const media::AudioParameters& params =
      device_under_test.GetOriginalSinkParamsForTesting();
  EXPECT_EQ(params.format(), media::AudioParameters::AUDIO_FAKE);
  EXPECT_EQ(params.sample_rate(), 48000);
  EXPECT_EQ(params.frames_per_buffer(), 480);
  EXPECT_TRUE(params.IsValid());
}

class RendererWebAudioDeviceImplLatencyAndSampleRateTest
    : public RendererWebAudioDeviceImplTest,
      public testing::WithParamInterface<
          std::tuple<blink::WebAudioLatencyHint::AudioContextLatencyCategory,
                     int>> {
 protected:
  void SetUp() override {
    if (std::get<0>(GetParam()) == blink::WebAudioLatencyHint::kCategoryExact) {
      // Simulate a 10ms exact latency.
      test_latency_hint_ = blink::WebAudioLatencyHint(/*seconds=*/0.01);
    } else {
      test_latency_hint_ = blink::WebAudioLatencyHint(std::get<0>(GetParam()));
    }

    int sample_rate = std::get<1>(GetParam());
    // sample_rate == 0 means no context_sample_rate is specified.
    if (sample_rate != 0) {
      context_sample_rate_ = static_cast<float>(sample_rate);
    }

    feature_list_.InitAndEnableFeature(
        features::kWebAudioRemoveAudioDestinationResampler);
  }

 protected:
  blink::WebAudioLatencyHint test_latency_hint_{
      blink::WebAudioLatencyHint::kCategoryInteractive};

 private:
  base::test::ScopedFeatureList feature_list_;
};

TEST_P(RendererWebAudioDeviceImplLatencyAndSampleRateTest,
       TestLatencyHintValues) {
  int context_sample_rate = context_sample_rate_.value_or(kHardwareSampleRate);
  media::AudioParameters hardware_params(
      media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
      media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate,
      kHardwareBufferSize);
  int expected_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize(
      test_latency_hint_, context_sample_rate, hardware_params);

  SetupDevice(test_latency_hint_);

  EXPECT_EQ(webaudio_device_->SampleRate(), context_sample_rate);
  EXPECT_EQ(webaudio_device_->FramesPerBuffer(), expected_buffer_size);

  webaudio_device_->Start();
  EXPECT_EQ(webaudio_device_->SampleRate(), context_sample_rate);
  EXPECT_EQ(webaudio_device_->FramesPerBuffer(), expected_buffer_size);

  webaudio_device_->Stop();
  EXPECT_EQ(webaudio_device_->SampleRate(), context_sample_rate);
  EXPECT_EQ(webaudio_device_->FramesPerBuffer(), expected_buffer_size);
}

INSTANTIATE_TEST_SUITE_P(
    All,
    RendererWebAudioDeviceImplLatencyAndSampleRateTest,
    testing::Combine(

        testing::Values(blink::WebAudioLatencyHint::kCategoryInteractive,
                        blink::WebAudioLatencyHint::kCategoryBalanced,
                        blink::WebAudioLatencyHint::kCategoryPlayback,
                        blink::WebAudioLatencyHint::kCategoryExact),
        // User provided sample rate; 0 means no sample rate provided.
        testing::Values(0, 16000, 44100, 48000, 96000)));

}  // namespace content
