// Copyright 2013 The Chromium 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 "base/macros.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_timeouts.h"
#include "build/build_config.h"
#include "content/public/renderer/media_stream_audio_sink.h"
#include "content/renderer/media/media_stream_audio_source.h"
#include "content/renderer/media/mock_constraint_factory.h"
#include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h"
#include "content/renderer/media/webrtc_audio_capturer.h"
#include "content/renderer/media/webrtc_local_audio_track.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_capturer_source.h"
#include "media/base/audio_parameters.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebMediaConstraints.h"
#include "third_party/WebKit/public/web/WebHeap.h"
#include "third_party/webrtc/api/mediastreaminterface.h"

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::AtLeast;
using ::testing::Return;

namespace content {

namespace {

ACTION_P(SignalEvent, event) {
  event->Signal();
}

// A simple thread that we use to fake the audio thread which provides data to
// the |WebRtcAudioCapturer|.
class FakeAudioThread : public base::PlatformThread::Delegate {
 public:
  FakeAudioThread(WebRtcAudioCapturer* capturer,
                  const media::AudioParameters& params)
    : capturer_(capturer),
      thread_(),
      closure_(false, false) {
    DCHECK(capturer);
    audio_bus_ = media::AudioBus::Create(params);
  }

  ~FakeAudioThread() override { DCHECK(thread_.is_null()); }

  // base::PlatformThread::Delegate:
  void ThreadMain() override {
    while (true) {
      if (closure_.IsSignaled())
        return;

      media::AudioCapturerSource::CaptureCallback* callback =
          static_cast<media::AudioCapturerSource::CaptureCallback*>(
              capturer_);
      audio_bus_->Zero();
      callback->Capture(audio_bus_.get(), 0, 0, false);

      // Sleep 1ms to yield the resource for the main thread.
      base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
    }
  }

  void Start() {
    base::PlatformThread::CreateWithPriority(
        0, this, &thread_, base::ThreadPriority::REALTIME_AUDIO);
    CHECK(!thread_.is_null());
  }

  void Stop() {
    closure_.Signal();
    base::PlatformThread::Join(thread_);
    thread_ = base::PlatformThreadHandle();
  }

 private:
  std::unique_ptr<media::AudioBus> audio_bus_;
  WebRtcAudioCapturer* capturer_;
  base::PlatformThreadHandle thread_;
  base::WaitableEvent closure_;
  DISALLOW_COPY_AND_ASSIGN(FakeAudioThread);
};

class MockCapturerSource : public media::AudioCapturerSource {
 public:
  explicit MockCapturerSource(WebRtcAudioCapturer* capturer)
      : capturer_(capturer) {}
  MOCK_METHOD3(OnInitialize, void(const media::AudioParameters& params,
                                  CaptureCallback* callback,
                                  int session_id));
  MOCK_METHOD0(OnStart, void());
  MOCK_METHOD0(OnStop, void());
  void SetVolume(double volume) final {}
  MOCK_METHOD1(SetAutomaticGainControl, void(bool enable));

  void Initialize(const media::AudioParameters& params,
                  CaptureCallback* callback,
                  int session_id) override {
    DCHECK(params.IsValid());
    params_ = params;
    OnInitialize(params, callback, session_id);
  }
  void Start() override {
    audio_thread_.reset(new FakeAudioThread(capturer_, params_));
    audio_thread_->Start();
    OnStart();
  }
  void Stop() override {
    audio_thread_->Stop();
    audio_thread_.reset();
    OnStop();
  }

 protected:
  ~MockCapturerSource() override {}

 private:
  std::unique_ptr<FakeAudioThread> audio_thread_;
  WebRtcAudioCapturer* capturer_;
  media::AudioParameters params_;
};

class MockMediaStreamAudioSink : public MediaStreamAudioSink {
 public:
  MockMediaStreamAudioSink() {}
  ~MockMediaStreamAudioSink() {}
  void OnData(const media::AudioBus& audio_bus,
              base::TimeTicks estimated_capture_time) override {
    EXPECT_EQ(params_.channels(), audio_bus.channels());
    EXPECT_EQ(params_.frames_per_buffer(), audio_bus.frames());
    EXPECT_FALSE(estimated_capture_time.is_null());
    CaptureData();
  }
  MOCK_METHOD0(CaptureData, void());
  void OnSetFormat(const media::AudioParameters& params) {
    params_ = params;
    FormatIsSet();
  }
  MOCK_METHOD0(FormatIsSet, void());

  const media::AudioParameters& audio_params() const { return params_; }

 private:
  media::AudioParameters params_;
};

}  // namespace

class WebRtcLocalAudioTrackTest : public ::testing::Test {
 protected:
  void SetUp() override {
    params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
                  media::CHANNEL_LAYOUT_STEREO, 48000, 16, 480);
    MockConstraintFactory constraint_factory;
    blink_source_.initialize("dummy", blink::WebMediaStreamSource::TypeAudio,
                             "dummy",
                             false /* remote */);
    MediaStreamAudioSource* audio_source = new MediaStreamAudioSource();
    blink_source_.setExtraData(audio_source);

    StreamDeviceInfo device(MEDIA_DEVICE_AUDIO_CAPTURE,
                            std::string(), std::string());
    {
      std::unique_ptr<WebRtcAudioCapturer> capturer =
          WebRtcAudioCapturer::CreateCapturer(
              -1, device, constraint_factory.CreateWebMediaConstraints(),
              nullptr, audio_source);
      capturer_ = capturer.get();
      audio_source->SetAudioCapturer(std::move(capturer));
    }
    capturer_source_ = new MockCapturerSource(capturer_);
    EXPECT_CALL(*capturer_source_.get(), OnInitialize(_, capturer_, -1))
        .WillOnce(Return());
    EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
    EXPECT_CALL(*capturer_source_.get(), OnStart());
    capturer_->SetCapturerSource(capturer_source_, params_);
  }

  void TearDown() override {
    blink_source_.reset();
    blink::WebHeap::collectAllGarbageForTesting();
  }

  media::AudioParameters params_;
  blink::WebMediaStreamSource blink_source_;
  WebRtcAudioCapturer* capturer_;  // Owned by |blink_source_|.
  scoped_refptr<MockCapturerSource> capturer_source_;
};

// Creates a capturer and audio track, fakes its audio thread, and
// connect/disconnect the sink to the audio track on the fly, the sink should
// get data callback when the track is connected to the capturer but not when
// the track is disconnected from the capturer.
TEST_F(WebRtcLocalAudioTrackTest, ConnectAndDisconnectOneSink) {
  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter(
      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
  std::unique_ptr<WebRtcLocalAudioTrack> track(
      new WebRtcLocalAudioTrack(adapter.get()));
  track->Start(
      base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo,
                 MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(),
                 track.get()));
  capturer_->AddTrack(track.get());
  EXPECT_TRUE(track->GetAudioAdapter()->enabled());

  std::unique_ptr<MockMediaStreamAudioSink> sink(
      new MockMediaStreamAudioSink());
  base::WaitableEvent event(false, false);
  EXPECT_CALL(*sink, FormatIsSet());
  EXPECT_CALL(*sink,
      CaptureData()).Times(AtLeast(1))
      .WillRepeatedly(SignalEvent(&event));
  track->AddSink(sink.get());
  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
  track->RemoveSink(sink.get());

  EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return());
  capturer_->Stop();
}

// The same setup as ConnectAndDisconnectOneSink, but enable and disable the
// audio track on the fly. When the audio track is disabled, there is no data
// callback to the sink; when the audio track is enabled, there comes data
// callback.
// TODO(xians): Enable this test after resolving the racing issue that TSAN
// reports on MediaStreamTrack::enabled();
TEST_F(WebRtcLocalAudioTrackTest,  DISABLED_DisableEnableAudioTrack) {
  EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
  EXPECT_CALL(*capturer_source_.get(), OnStart());
  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter(
      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
  std::unique_ptr<WebRtcLocalAudioTrack> track(
      new WebRtcLocalAudioTrack(adapter.get()));
  track->Start(
      base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo,
                 MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(),
                 track.get()));
  capturer_->AddTrack(track.get());
  EXPECT_TRUE(track->GetAudioAdapter()->enabled());
  EXPECT_TRUE(track->GetAudioAdapter()->set_enabled(false));
  std::unique_ptr<MockMediaStreamAudioSink> sink(
      new MockMediaStreamAudioSink());
  const media::AudioParameters params = capturer_->GetInputFormat();
  base::WaitableEvent event(false, false);
  EXPECT_CALL(*sink, FormatIsSet()).Times(1);
  EXPECT_CALL(*sink, CaptureData()).Times(0);
  EXPECT_EQ(sink->audio_params().frames_per_buffer(),
            params.sample_rate() / 100);
  track->AddSink(sink.get());
  EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout()));

  event.Reset();
  EXPECT_CALL(*sink, CaptureData()).Times(AtLeast(1))
      .WillRepeatedly(SignalEvent(&event));
  EXPECT_TRUE(track->GetAudioAdapter()->set_enabled(true));
  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
  track->RemoveSink(sink.get());

  EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return());
  capturer_->Stop();
  track.reset();
}

// Create multiple audio tracks and enable/disable them, verify that the audio
// callbacks appear/disappear.
// Flaky due to a data race, see http://crbug.com/295418
TEST_F(WebRtcLocalAudioTrackTest, DISABLED_MultipleAudioTracks) {
  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1(
      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
  std::unique_ptr<WebRtcLocalAudioTrack> track_1(
      new WebRtcLocalAudioTrack(adapter_1.get()));
  track_1->Start(
      base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo,
                 MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(),
                 track_1.get()));
  capturer_->AddTrack(track_1.get());
  EXPECT_TRUE(track_1->GetAudioAdapter()->enabled());
  std::unique_ptr<MockMediaStreamAudioSink> sink_1(
      new MockMediaStreamAudioSink());
  const media::AudioParameters params = capturer_->GetInputFormat();
  base::WaitableEvent event_1(false, false);
  EXPECT_CALL(*sink_1, FormatIsSet()).WillOnce(Return());
  EXPECT_CALL(*sink_1, CaptureData()).Times(AtLeast(1))
      .WillRepeatedly(SignalEvent(&event_1));
  EXPECT_EQ(sink_1->audio_params().frames_per_buffer(),
            params.sample_rate() / 100);
  track_1->AddSink(sink_1.get());
  EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout()));

  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2(
      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
  std::unique_ptr<WebRtcLocalAudioTrack> track_2(
      new WebRtcLocalAudioTrack(adapter_2.get()));
  track_2->Start(
      base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo,
                 MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(),
                 track_2.get()));
  capturer_->AddTrack(track_2.get());
  EXPECT_TRUE(track_2->GetAudioAdapter()->enabled());

  // Verify both |sink_1| and |sink_2| get data.
  event_1.Reset();
  base::WaitableEvent event_2(false, false);

  std::unique_ptr<MockMediaStreamAudioSink> sink_2(
      new MockMediaStreamAudioSink());
  EXPECT_CALL(*sink_2, FormatIsSet()).WillOnce(Return());
  EXPECT_CALL(*sink_1, CaptureData()).Times(AtLeast(1))
      .WillRepeatedly(SignalEvent(&event_1));
  EXPECT_EQ(sink_1->audio_params().frames_per_buffer(),
            params.sample_rate() / 100);
  EXPECT_CALL(*sink_2, CaptureData()).Times(AtLeast(1))
      .WillRepeatedly(SignalEvent(&event_2));
  EXPECT_EQ(sink_2->audio_params().frames_per_buffer(),
            params.sample_rate() / 100);
  track_2->AddSink(sink_2.get());
  EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout()));
  EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout()));

  track_1->RemoveSink(sink_1.get());
  track_1->Stop();
  track_1.reset();

  EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return());
  track_2->RemoveSink(sink_2.get());
  track_2->Stop();
  track_2.reset();
}


// Start one track and verify the capturer is correctly starting its source.
// And it should be fine to not to call Stop() explicitly.
TEST_F(WebRtcLocalAudioTrackTest, StartOneAudioTrack) {
  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter(
      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
  std::unique_ptr<WebRtcLocalAudioTrack> track(
      new WebRtcLocalAudioTrack(adapter.get()));
  track->Start(
      base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo,
                 MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(),
                 track.get()));
  capturer_->AddTrack(track.get());

  // When the track goes away, it will automatically stop the
  // |capturer_source_|.
  EXPECT_CALL(*capturer_source_.get(), OnStop());
  track.reset();
}

// Start two tracks and verify the capturer is correctly starting its source.
// When the last track connected to the capturer is stopped, the source is
// stopped.
TEST_F(WebRtcLocalAudioTrackTest, StartTwoAudioTracks) {
  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter1(
      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
  std::unique_ptr<WebRtcLocalAudioTrack> track1(
      new WebRtcLocalAudioTrack(adapter1.get()));
  track1->Start(
      base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo,
                 MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(),
                 track1.get()));
  capturer_->AddTrack(track1.get());

  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter2(
        WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
  std::unique_ptr<WebRtcLocalAudioTrack> track2(
      new WebRtcLocalAudioTrack(adapter2.get()));
  track2->Start(
      base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo,
                 MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(),
                 track2.get()));
  capturer_->AddTrack(track2.get());

  track1->Stop();
  // When the last track is stopped, it will automatically stop the
  // |capturer_source_|.
  EXPECT_CALL(*capturer_source_.get(), OnStop());
  track2->Stop();
}

// Start/Stop tracks and verify the capturer is correctly starting/stopping
// its source.
TEST_F(WebRtcLocalAudioTrackTest, StartAndStopAudioTracks) {
  base::WaitableEvent event(false, false);
  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1(
      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
  std::unique_ptr<WebRtcLocalAudioTrack> track_1(
      new WebRtcLocalAudioTrack(adapter_1.get()));
  track_1->Start(
      base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo,
                 MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(),
                 track_1.get()));
  capturer_->AddTrack(track_1.get());

  // Verify the data flow by connecting the sink to |track_1|.
  std::unique_ptr<MockMediaStreamAudioSink> sink(
      new MockMediaStreamAudioSink());
  event.Reset();
  EXPECT_CALL(*sink, FormatIsSet()).WillOnce(SignalEvent(&event));
  EXPECT_CALL(*sink, CaptureData())
      .Times(AnyNumber()).WillRepeatedly(Return());
  track_1->AddSink(sink.get());
  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));

  // Start the second audio track will not start the |capturer_source_|
  // since it has been started.
  EXPECT_CALL(*capturer_source_.get(), OnStart()).Times(0);
  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2(
      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
  std::unique_ptr<WebRtcLocalAudioTrack> track_2(
      new WebRtcLocalAudioTrack(adapter_2.get()));
  track_2->Start(
      base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo,
                 MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(),
                 track_2.get()));
  capturer_->AddTrack(track_2.get());

  // Stop the capturer will clear up the track lists in the capturer.
  EXPECT_CALL(*capturer_source_.get(), OnStop());
  capturer_->Stop();

  // Adding a new track to the capturer.
  track_2->AddSink(sink.get());
  EXPECT_CALL(*sink, FormatIsSet()).Times(0);

  // Stop the capturer again will not trigger stopping the source of the
  // capturer again..
  event.Reset();
  EXPECT_CALL(*capturer_source_.get(), OnStop()).Times(0);
  capturer_->Stop();
}

// Create a new capturer with new source, connect it to a new audio track.
#if defined(THREAD_SANITIZER)
// Fails under TSan, see https://crbug.com/576634.
#define MAYBE_ConnectTracksToDifferentCapturers \
    DISABLED_ConnectTracksToDifferentCapturers
#else
#define MAYBE_ConnectTracksToDifferentCapturers \
    ConnectTracksToDifferentCapturers
#endif
TEST_F(WebRtcLocalAudioTrackTest, MAYBE_ConnectTracksToDifferentCapturers) {
  // Setup the first audio track and start it.
  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1(
      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
  std::unique_ptr<WebRtcLocalAudioTrack> track_1(
      new WebRtcLocalAudioTrack(adapter_1.get()));
  track_1->Start(
      base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo,
                 MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(),
                 track_1.get()));
  capturer_->AddTrack(track_1.get());

  // Verify the data flow by connecting the |sink_1| to |track_1|.
  std::unique_ptr<MockMediaStreamAudioSink> sink_1(
      new MockMediaStreamAudioSink());
  EXPECT_CALL(*sink_1.get(), CaptureData())
      .Times(AnyNumber()).WillRepeatedly(Return());
  EXPECT_CALL(*sink_1.get(), FormatIsSet()).Times(AnyNumber());
  track_1->AddSink(sink_1.get());

  // Create a new capturer with new source with different audio format.
  MockConstraintFactory constraint_factory;
  StreamDeviceInfo device(MEDIA_DEVICE_AUDIO_CAPTURE,
                          std::string(), std::string());
  std::unique_ptr<WebRtcAudioCapturer> new_capturer(
      WebRtcAudioCapturer::CreateCapturer(
          -1, device, constraint_factory.CreateWebMediaConstraints(), NULL,
          NULL));
  scoped_refptr<MockCapturerSource> new_source(
      new MockCapturerSource(new_capturer.get()));
  EXPECT_CALL(*new_source.get(), OnInitialize(_, new_capturer.get(), -1));
  EXPECT_CALL(*new_source.get(), SetAutomaticGainControl(true));
  EXPECT_CALL(*new_source.get(), OnStart());

  media::AudioParameters new_param(
      media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
      media::CHANNEL_LAYOUT_MONO, 44100, 16, 441);
  new_capturer->SetCapturerSource(new_source, new_param);

  // Setup the second audio track, connect it to the new capturer and start it.
  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2(
      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
  std::unique_ptr<WebRtcLocalAudioTrack> track_2(
      new WebRtcLocalAudioTrack(adapter_2.get()));
  track_2->Start(
      base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo,
                 MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(),
                 track_2.get()));
  new_capturer->AddTrack(track_2.get());

  // Verify the data flow by connecting the |sink_2| to |track_2|.
  std::unique_ptr<MockMediaStreamAudioSink> sink_2(
      new MockMediaStreamAudioSink());
  base::WaitableEvent event(false, false);
  EXPECT_CALL(*sink_2, CaptureData())
      .Times(AnyNumber()).WillRepeatedly(Return());
  EXPECT_CALL(*sink_2, FormatIsSet()).WillOnce(SignalEvent(&event));
  track_2->AddSink(sink_2.get());
  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));

  // Stopping the new source will stop the second track.
  event.Reset();
  EXPECT_CALL(*new_source.get(), OnStop())
      .Times(1).WillOnce(SignalEvent(&event));
  new_capturer->Stop();
  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));

  // Stop the capturer of the first audio track.
  EXPECT_CALL(*capturer_source_.get(), OnStop());
  capturer_->Stop();
}

// Make sure a audio track can deliver packets with a buffer size smaller than
// 10ms when it is not connected with a peer connection.
TEST_F(WebRtcLocalAudioTrackTest, TrackWorkWithSmallBufferSize) {
  // Setup a capturer which works with a buffer size smaller than 10ms.
  media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
                                media::CHANNEL_LAYOUT_STEREO, 48000, 16, 128);

  // Create a capturer with new source which works with the format above.
  MockConstraintFactory factory;
  factory.DisableDefaultAudioConstraints();
  std::unique_ptr<WebRtcAudioCapturer> capturer(
      WebRtcAudioCapturer::CreateCapturer(
          -1, StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE, "", "",
                               params.sample_rate(), params.channel_layout(),
                               params.frames_per_buffer()),
          factory.CreateWebMediaConstraints(), NULL, NULL));
  scoped_refptr<MockCapturerSource> source(
      new MockCapturerSource(capturer.get()));
  EXPECT_CALL(*source.get(), OnInitialize(_, capturer.get(), -1));
  EXPECT_CALL(*source.get(), SetAutomaticGainControl(true));
  EXPECT_CALL(*source.get(), OnStart());
  capturer->SetCapturerSource(source, params);

  // Setup a audio track, connect it to the capturer and start it.
  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter(
      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
  std::unique_ptr<WebRtcLocalAudioTrack> track(
      new WebRtcLocalAudioTrack(adapter.get()));
  track->Start(
      base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo,
                 MediaStreamAudioSource::From(blink_source_)->GetWeakPtr(),
                 track.get()));
  capturer->AddTrack(track.get());

  // Verify the data flow by connecting the |sink| to |track|.
  std::unique_ptr<MockMediaStreamAudioSink> sink(
      new MockMediaStreamAudioSink());
  base::WaitableEvent event(false, false);
  EXPECT_CALL(*sink, FormatIsSet()).Times(1);
  // Verify the sinks are getting the packets with an expecting buffer size.
#if defined(OS_ANDROID)
  const int expected_buffer_size = params.sample_rate() / 100;
#else
  const int expected_buffer_size = params.frames_per_buffer();
#endif
  EXPECT_CALL(*sink, CaptureData())
      .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event));
  track->AddSink(sink.get());
  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
  EXPECT_EQ(expected_buffer_size, sink->audio_params().frames_per_buffer());

  // Stopping the new source will stop the second track.
  EXPECT_CALL(*source.get(), OnStop()).Times(1);
  capturer->Stop();

  // Even though this test don't use |capturer_source_| it will be stopped
  // during teardown of the test harness.
  EXPECT_CALL(*capturer_source_.get(), OnStop());
}

}  // namespace content
