webrtc_local_audio_track_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Copyright 2013 The Chromium Authors. All rights reserved.
256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Use of this source code is governed by a BSD-style license that can be
356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// found in the LICENSE file.
456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "base/synchronization/waitable_event.h"
656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "base/test/test_timeouts.h"
756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "content/renderer/media/mock_media_constraint_factory.h"
856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h"
956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "content/renderer/media/webrtc_audio_capturer.h"
107df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "content/renderer/media/webrtc_audio_device_impl.h"
117df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "content/renderer/media/webrtc_local_audio_source_provider.h"
127df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "content/renderer/media/webrtc_local_audio_track.h"
137df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "media/audio/audio_parameters.h"
147df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "media/base/audio_bus.h"
157df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "media/base/audio_capturer_source.h"
167df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "testing/gmock/include/gmock/gmock.h"
177df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "testing/gtest/include/gtest/gtest.h"
187df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "third_party/WebKit/public/platform/WebMediaConstraints.h"
197df30109963092559d3760c0661a020f9daf1030The Android Open Source Project#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
207df30109963092559d3760c0661a020f9daf1030The Android Open Source Project
217df30109963092559d3760c0661a020f9daf1030The Android Open Source Projectusing ::testing::_;
2256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksusing ::testing::AnyNumber;
2356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksusing ::testing::AtLeast;
2456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksusing ::testing::Return;
2556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
2656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksnamespace content {
2756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
2856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksnamespace {
2956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
3056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksACTION_P(SignalEvent, event) {
3156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  event->Signal();
3256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
3356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
3456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// A simple thread that we use to fake the audio thread which provides data to
3556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// the |WebRtcAudioCapturer|.
3656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksclass FakeAudioThread : public base::PlatformThread::Delegate {
3756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks public:
3856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  FakeAudioThread(const scoped_refptr<WebRtcAudioCapturer>& capturer,
3956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                  const media::AudioParameters& params)
4056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    : capturer_(capturer),
4156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      thread_(),
4256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      closure_(false, false) {
4356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    DCHECK(capturer.get());
4456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    audio_bus_ = media::AudioBus::Create(params);
4556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  }
4656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
4756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  virtual ~FakeAudioThread() { DCHECK(thread_.is_null()); }
4856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
4956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // base::PlatformThread::Delegate:
5056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  virtual void ThreadMain() OVERRIDE {
5156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    while (true) {
5256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      if (closure_.IsSignaled())
5356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        return;
5456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
5556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      media::AudioCapturerSource::CaptureCallback* callback =
5656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks          static_cast<media::AudioCapturerSource::CaptureCallback*>(
5756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks              capturer_.get());
5856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      audio_bus_->Zero();
5956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      callback->Capture(audio_bus_.get(), 0, 0, false);
6056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
6156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      // Sleep 1ms to yield the resource for the main thread.
6256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
6356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
6456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  }
6556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
6656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  void Start() {
6756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    base::PlatformThread::CreateWithPriority(
6856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        0, this, &thread_, base::kThreadPriority_RealtimeAudio);
6956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    CHECK(!thread_.is_null());
7056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  }
7156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
7256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  void Stop() {
7356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    closure_.Signal();
7456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    base::PlatformThread::Join(thread_);
7556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    thread_ = base::PlatformThreadHandle();
7656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  }
7756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
7856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks private:
7956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<media::AudioBus> audio_bus_;
8056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<WebRtcAudioCapturer> capturer_;
8156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  base::PlatformThreadHandle thread_;
8256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  base::WaitableEvent closure_;
8356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  DISALLOW_COPY_AND_ASSIGN(FakeAudioThread);
8456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks};
8556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
8656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksclass MockCapturerSource : public media::AudioCapturerSource {
8756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks public:
8856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  explicit MockCapturerSource(WebRtcAudioCapturer* capturer)
8956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      : capturer_(capturer) {}
9056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  MOCK_METHOD3(OnInitialize, void(const media::AudioParameters& params,
9156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                                  CaptureCallback* callback,
9256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                                  int session_id));
9356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  MOCK_METHOD0(OnStart, void());
9456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  MOCK_METHOD0(OnStop, void());
9556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  MOCK_METHOD1(SetVolume, void(double volume));
9656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  MOCK_METHOD1(SetAutomaticGainControl, void(bool enable));
9756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
9856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  virtual void Initialize(const media::AudioParameters& params,
9956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                          CaptureCallback* callback,
10056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                          int session_id) OVERRIDE {
10156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    DCHECK(params.IsValid());
10256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    params_ = params;
10356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    OnInitialize(params, callback, session_id);
10456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  }
10556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  virtual void Start() OVERRIDE {
10656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    audio_thread_.reset(new FakeAudioThread(capturer_, params_));
10756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    audio_thread_->Start();
10856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    OnStart();
10956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  }
11056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  virtual void Stop() OVERRIDE {
11156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    audio_thread_->Stop();
11256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    audio_thread_.reset();
11356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    OnStop();
11456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  }
11556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks protected:
11656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  virtual ~MockCapturerSource() {}
11756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
11856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks private:
11956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<FakeAudioThread> audio_thread_;
12056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  WebRtcAudioCapturer* capturer_;
12156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  media::AudioParameters params_;
12256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks};
12356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
12456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// TODO(xians): Use MediaStreamAudioSink.
12556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksclass MockMediaStreamAudioSink : public PeerConnectionAudioSink {
12656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks public:
12756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  MockMediaStreamAudioSink() {}
12856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  ~MockMediaStreamAudioSink() {}
12956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  int OnData(const int16* audio_data,
13056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks             int sample_rate,
13156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks             int number_of_channels,
13256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks             int number_of_frames,
13356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks             const std::vector<int>& channels,
13456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks             int audio_delay_milliseconds,
13556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks             int current_volume,
13656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks             bool need_audio_processing,
13756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks             bool key_pressed) OVERRIDE {
13856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EXPECT_EQ(params_.sample_rate(), sample_rate);
13956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EXPECT_EQ(params_.channels(), number_of_channels);
14056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EXPECT_EQ(params_.frames_per_buffer(), number_of_frames);
14156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    CaptureData(channels.size(),
14256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                audio_delay_milliseconds,
14356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                current_volume,
14456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                need_audio_processing,
14556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                key_pressed);
14656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    return 0;
14756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  }
14856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  MOCK_METHOD5(CaptureData,
14956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks               void(int number_of_network_channels,
15056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    int audio_delay_milliseconds,
15156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    int current_volume,
15256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    bool need_audio_processing,
15356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    bool key_pressed));
15456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  void OnSetFormat(const media::AudioParameters& params) {
15556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    params_ = params;
15656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    FormatIsSet();
15756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  }
15856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  MOCK_METHOD0(FormatIsSet, void());
15956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
16056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  const media::AudioParameters& audio_params() const { return params_; }
16156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
16256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks private:
16356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  media::AudioParameters params_;
16456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks};
16556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
16656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}  // namespace
16756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
16856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksclass WebRtcLocalAudioTrackTest : public ::testing::Test {
16956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks protected:
17056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  virtual void SetUp() OVERRIDE {
17156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
17256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                  media::CHANNEL_LAYOUT_STEREO, 2, 0, 48000, 16, 480);
17356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    blink::WebMediaConstraints constraints;
17456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    StreamDeviceInfo device(MEDIA_DEVICE_AUDIO_CAPTURE,
17556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                            std::string(), std::string());
17656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    capturer_ = WebRtcAudioCapturer::CreateCapturer(-1, device,
17756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                                                    constraints, NULL);
17856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    capturer_source_ = new MockCapturerSource(capturer_.get());
17956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EXPECT_CALL(*capturer_source_.get(), OnInitialize(_, capturer_.get(), -1))
18056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        .WillOnce(Return());
18156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    capturer_->SetCapturerSourceForTesting(capturer_source_, params_);
18256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  }
18356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
18456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  media::AudioParameters params_;
18556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<MockCapturerSource> capturer_source_;
18656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<WebRtcAudioCapturer> capturer_;
18756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks};
18856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
18956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Creates a capturer and audio track, fakes its audio thread, and
19056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// connect/disconnect the sink to the audio track on the fly, the sink should
19156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// get data callback when the track is connected to the capturer but not when
19256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// the track is disconnected from the capturer.
19356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksTEST_F(WebRtcLocalAudioTrackTest, ConnectAndDisconnectOneSink) {
19456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
19556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), OnStart());
19656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter(
19756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
19856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<WebRtcLocalAudioTrack> track(
19956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      new WebRtcLocalAudioTrack(adapter, capturer_, NULL));
20056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<WebRtcLocalAudioSourceProvider*>(
20156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      track->audio_source_provider())->SetSinkParamsForTesting(params_);
20256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track->Start();
20356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(track->GetAudioAdapter()->enabled());
20456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
20556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Connect a number of network channels to the audio track.
20656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static const int kNumberOfNetworkChannels = 4;
20756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  for (int i = 0; i < kNumberOfNetworkChannels; ++i) {
20856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    static_cast<webrtc::AudioTrackInterface*>(
20956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        adapter.get())->GetRenderer()->AddChannel(i);
21056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  }
21156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink());
21256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  base::WaitableEvent event(false, false);
21356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink, FormatIsSet());
21456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink,
21556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      CaptureData(kNumberOfNetworkChannels,
21656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                  0,
21756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                  0,
21856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                  _,
21956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                  false)).Times(AtLeast(1))
22056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      .WillRepeatedly(SignalEvent(&event));
22156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track->AddSink(sink.get());
22256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
22356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track->RemoveSink(sink.get());
22456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
22556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return());
22656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  capturer_->Stop();
22756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
22856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
22956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// The same setup as ConnectAndDisconnectOneSink, but enable and disable the
23056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// audio track on the fly. When the audio track is disabled, there is no data
23156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// callback to the sink; when the audio track is enabled, there comes data
23256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// callback.
23356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// TODO(xians): Enable this test after resolving the racing issue that TSAN
23456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// reports on MediaStreamTrack::enabled();
23556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksTEST_F(WebRtcLocalAudioTrackTest,  DISABLED_DisableEnableAudioTrack) {
23656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
23756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), OnStart());
23856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter(
23956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
24056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<WebRtcLocalAudioTrack> track(
24156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      new WebRtcLocalAudioTrack(adapter, capturer_, NULL));
24256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<WebRtcLocalAudioSourceProvider*>(
24356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      track->audio_source_provider())->SetSinkParamsForTesting(params_);
24456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track->Start();
24556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<webrtc::AudioTrackInterface*>(
24656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      adapter.get())->GetRenderer()->AddChannel(0);
24756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(track->GetAudioAdapter()->enabled());
24856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(track->GetAudioAdapter()->set_enabled(false));
24956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink());
25056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  const media::AudioParameters params = capturer_->source_audio_parameters();
25156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  base::WaitableEvent event(false, false);
25256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink, FormatIsSet()).Times(1);
25356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink,
25456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks              CaptureData(1, 0, 0, _, false)).Times(0);
25556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_EQ(sink->audio_params().frames_per_buffer(),
25656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            params.sample_rate() / 100);
25756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track->AddSink(sink.get());
25856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout()));
25956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
26056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  event.Reset();
26156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink,
26256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks              CaptureData(1, 0, 0, _, false)).Times(AtLeast(1))
26356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      .WillRepeatedly(SignalEvent(&event));
26456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(track->GetAudioAdapter()->set_enabled(true));
26556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
26656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track->RemoveSink(sink.get());
26756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
26856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return());
26956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  capturer_->Stop();
27056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track.reset();
27156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
27256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
27356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Create multiple audio tracks and enable/disable them, verify that the audio
27456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// callbacks appear/disappear.
27556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Flaky due to a data race, see http://crbug.com/295418
27656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksTEST_F(WebRtcLocalAudioTrackTest, DISABLED_MultipleAudioTracks) {
27756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
27856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), OnStart());
27956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1(
28056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
28156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<WebRtcLocalAudioTrack> track_1(
28256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    new WebRtcLocalAudioTrack(adapter_1, capturer_, NULL));
28356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<WebRtcLocalAudioSourceProvider*>(
28456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      track_1->audio_source_provider())->SetSinkParamsForTesting(params_);
28556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_1->Start();
28656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<webrtc::AudioTrackInterface*>(
28756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      adapter_1.get())->GetRenderer()->AddChannel(0);
28856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(track_1->GetAudioAdapter()->enabled());
28956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<MockMediaStreamAudioSink> sink_1(new MockMediaStreamAudioSink());
29056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  const media::AudioParameters params = capturer_->source_audio_parameters();
29156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  base::WaitableEvent event_1(false, false);
29256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink_1, FormatIsSet()).WillOnce(Return());
29356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink_1,
29456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      CaptureData(1, 0, 0, _, false)).Times(AtLeast(1))
29556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      .WillRepeatedly(SignalEvent(&event_1));
29656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_EQ(sink_1->audio_params().frames_per_buffer(),
29756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            params.sample_rate() / 100);
29856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_1->AddSink(sink_1.get());
29956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout()));
30056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
30156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2(
30256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
30356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<WebRtcLocalAudioTrack> track_2(
30456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    new WebRtcLocalAudioTrack(adapter_2, capturer_, NULL));
30556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<WebRtcLocalAudioSourceProvider*>(
30656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      track_2->audio_source_provider())->SetSinkParamsForTesting(params_);
30756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_2->Start();
30856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<webrtc::AudioTrackInterface*>(
30956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      adapter_2.get())->GetRenderer()->AddChannel(1);
31056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(track_2->GetAudioAdapter()->enabled());
31156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
31256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Verify both |sink_1| and |sink_2| get data.
31356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  event_1.Reset();
31456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  base::WaitableEvent event_2(false, false);
31556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
31656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<MockMediaStreamAudioSink> sink_2(new MockMediaStreamAudioSink());
31756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink_2, FormatIsSet()).WillOnce(Return());
31856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink_1, CaptureData(1, 0, 0, _, false)).Times(AtLeast(1))
31956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      .WillRepeatedly(SignalEvent(&event_1));
32056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_EQ(sink_1->audio_params().frames_per_buffer(),
32156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            params.sample_rate() / 100);
32256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink_2, CaptureData(1, 0, 0, _, false)).Times(AtLeast(1))
32356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      .WillRepeatedly(SignalEvent(&event_2));
32456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_EQ(sink_2->audio_params().frames_per_buffer(),
32556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            params.sample_rate() / 100);
32656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_2->AddSink(sink_2.get());
32756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout()));
32856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout()));
32956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
33056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_1->RemoveSink(sink_1.get());
33156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_1->Stop();
33256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_1.reset();
33356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
33456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return());
33556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_2->RemoveSink(sink_2.get());
33656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_2->Stop();
33756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_2.reset();
33856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
33956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  capturer_->Stop();
34056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
34156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
34256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
34356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Start one track and verify the capturer is correctly starting its source.
34456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// And it should be fine to not to call Stop() explicitly.
34556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksTEST_F(WebRtcLocalAudioTrackTest, StartOneAudioTrack) {
34656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
34756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), OnStart());
34856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter(
34956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
35056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<WebRtcLocalAudioTrack> track(
35156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      new WebRtcLocalAudioTrack(adapter, capturer_, NULL));
35256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<WebRtcLocalAudioSourceProvider*>(
35356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      track->audio_source_provider())->SetSinkParamsForTesting(params_);
35456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track->Start();
35556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
35656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // When the track goes away, it will automatically stop the
35756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // |capturer_source_|.
35856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), OnStop());
35956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  capturer_->Stop();
36056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track.reset();
36156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
36256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
36356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Start/Stop tracks and verify the capturer is correctly starting/stopping
36456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// its source.
36556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksTEST_F(WebRtcLocalAudioTrackTest, StartAndStopAudioTracks) {
36656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Starting the first audio track will start the |capturer_source_|.
36756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  base::WaitableEvent event(false, false);
36856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
36956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), OnStart()).WillOnce(SignalEvent(&event));
37056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1(
37156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
37256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<WebRtcLocalAudioTrack> track_1(
37356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      new WebRtcLocalAudioTrack(adapter_1, capturer_, NULL));
37456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<webrtc::AudioTrackInterface*>(
37556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      adapter_1.get())->GetRenderer()->AddChannel(0);
37656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<WebRtcLocalAudioSourceProvider*>(
37756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      track_1->audio_source_provider())->SetSinkParamsForTesting(params_);
37856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_1->Start();
37956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
38056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
38156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Verify the data flow by connecting the sink to |track_1|.
38256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink());
38356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  event.Reset();
38456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink, FormatIsSet()).WillOnce(SignalEvent(&event));
38556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink, CaptureData(_, 0, 0, _, false))
38656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      .Times(AnyNumber()).WillRepeatedly(Return());
38756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_1->AddSink(sink.get());
38856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
38956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
39056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Start the second audio track will not start the |capturer_source_|
39156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // since it has been started.
39256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), OnStart()).Times(0);
39356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2(
39456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
39556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<WebRtcLocalAudioTrack> track_2(
39656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      new WebRtcLocalAudioTrack(adapter_2, capturer_, NULL));
39756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<WebRtcLocalAudioSourceProvider*>(
39856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      track_2->audio_source_provider())->SetSinkParamsForTesting(params_);
39956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_2->Start();
40056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<webrtc::AudioTrackInterface*>(
40156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      adapter_2.get())->GetRenderer()->AddChannel(1);
40256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
40356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Stop the capturer will clear up the track lists in the capturer.
40456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), OnStop());
40556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  capturer_->Stop();
40656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
40756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Adding a new track to the capturer.
40856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_2->AddSink(sink.get());
40956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink, FormatIsSet()).Times(0);
41056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
41156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Stop the capturer again will not trigger stopping the source of the
41256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // capturer again..
41356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  event.Reset();
41456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), OnStop()).Times(0);
41556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  capturer_->Stop();
41656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
41756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
41856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Create a new capturer with new source, connect it to a new audio track.
41956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksTEST_F(WebRtcLocalAudioTrackTest, ConnectTracksToDifferentCapturers) {
42056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Setup the first audio track and start it.
42156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
42256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), OnStart());
42356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_1(
42456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
42556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<WebRtcLocalAudioTrack> track_1(
42656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      new WebRtcLocalAudioTrack(adapter_1, capturer_, NULL));
42756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<WebRtcLocalAudioSourceProvider*>(
42856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      track_1->audio_source_provider())->SetSinkParamsForTesting(params_);
42956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_1->Start();
43056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
43156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Connect a number of network channels to the |track_1|.
43256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static const int kNumberOfNetworkChannelsForTrack1 = 2;
43356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  for (int i = 0; i < kNumberOfNetworkChannelsForTrack1; ++i) {
43456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    static_cast<webrtc::AudioTrackInterface*>(
43556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        adapter_1.get())->GetRenderer()->AddChannel(i);
43656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  }
43756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Verify the data flow by connecting the |sink_1| to |track_1|.
43856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<MockMediaStreamAudioSink> sink_1(new MockMediaStreamAudioSink());
43956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink_1.get(),
44056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks              CaptureData(kNumberOfNetworkChannelsForTrack1,
44156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                          0, 0, _, false))
44256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      .Times(AnyNumber()).WillRepeatedly(Return());
44356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink_1.get(), FormatIsSet()).Times(AnyNumber());
44456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_1->AddSink(sink_1.get());
44556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
44656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Create a new capturer with new source with different audio format.
44756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  blink::WebMediaConstraints constraints;
44856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  StreamDeviceInfo device(MEDIA_DEVICE_AUDIO_CAPTURE,
44956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                          std::string(), std::string());
45056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<WebRtcAudioCapturer> new_capturer(
45156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      WebRtcAudioCapturer::CreateCapturer(-1, device, constraints, NULL));
45256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<MockCapturerSource> new_source(
45356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      new MockCapturerSource(new_capturer.get()));
45456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*new_source.get(), OnInitialize(_, new_capturer.get(), -1));
45556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  media::AudioParameters new_param(
45656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
45756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      media::CHANNEL_LAYOUT_MONO, 44100, 16, 441);
45856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  new_capturer->SetCapturerSourceForTesting(new_source, new_param);
45956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
46056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Setup the second audio track, connect it to the new capturer and start it.
46156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*new_source.get(), SetAutomaticGainControl(true));
46256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*new_source.get(), OnStart());
46356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter_2(
46456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
46556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<WebRtcLocalAudioTrack> track_2(
46656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      new WebRtcLocalAudioTrack(adapter_2, new_capturer, NULL));
46756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<WebRtcLocalAudioSourceProvider*>(
46856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      track_2->audio_source_provider())->SetSinkParamsForTesting(params_);
46956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_2->Start();
47056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
47156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Connect a number of network channels to the |track_2|.
47256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static const int kNumberOfNetworkChannelsForTrack2 = 3;
47356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  for (int i = 0; i < kNumberOfNetworkChannelsForTrack2; ++i) {
47456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    static_cast<webrtc::AudioTrackInterface*>(
47556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        adapter_2.get())->GetRenderer()->AddChannel(i);
47656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  }
47756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Verify the data flow by connecting the |sink_2| to |track_2|.
47856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<MockMediaStreamAudioSink> sink_2(new MockMediaStreamAudioSink());
47956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  base::WaitableEvent event(false, false);
48056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink_2,
48156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks              CaptureData(kNumberOfNetworkChannelsForTrack2, 0, 0, _, false))
48256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      .Times(AnyNumber()).WillRepeatedly(Return());
48356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink_2, FormatIsSet()).WillOnce(SignalEvent(&event));
48456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track_2->AddSink(sink_2.get());
48556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
48656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
48756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Stopping the new source will stop the second track.
48856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  event.Reset();
48956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*new_source.get(), OnStop())
49056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      .Times(1).WillOnce(SignalEvent(&event));
49156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  new_capturer->Stop();
49256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
49356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
49456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Stop the capturer of the first audio track.
49556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*capturer_source_.get(), OnStop());
49656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  capturer_->Stop();
49756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
49856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
49956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
50056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// Make sure a audio track can deliver packets with a buffer size smaller than
50156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// 10ms when it is not connected with a peer connection.
50256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksTEST_F(WebRtcLocalAudioTrackTest, TrackWorkWithSmallBufferSize) {
50356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Setup a capturer which works with a buffer size smaller than 10ms.
50456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
50556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                                media::CHANNEL_LAYOUT_STEREO, 48000, 16, 128);
50656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
50756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Create a capturer with new source which works with the format above.
50856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  MockMediaConstraintFactory factory;
50956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  factory.DisableDefaultAudioConstraints();
51056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<WebRtcAudioCapturer> capturer(
51156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      WebRtcAudioCapturer::CreateCapturer(
51256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks          -1,
51356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks          StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE,
51456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                           "", "", params.sample_rate(),
51556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                           params.channel_layout(),
51656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                           params.frames_per_buffer()),
51756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks          factory.CreateWebMediaConstraints(),
51856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks          NULL));
51956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<MockCapturerSource> source(
52056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      new MockCapturerSource(capturer.get()));
52156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*source.get(), OnInitialize(_, capturer.get(), -1));
52256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  capturer->SetCapturerSourceForTesting(source, params);
52356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
52456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Setup a audio track, connect it to the capturer and start it.
52556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*source.get(), SetAutomaticGainControl(true));
52656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*source.get(), OnStart());
52756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter(
52856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
52956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<WebRtcLocalAudioTrack> track(
53056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      new WebRtcLocalAudioTrack(adapter, capturer, NULL));
53156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  static_cast<WebRtcLocalAudioSourceProvider*>(
53256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      track->audio_source_provider())->SetSinkParamsForTesting(params);
53356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track->Start();
53456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
53556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Verify the data flow by connecting the |sink| to |track|.
53656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink());
53756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  base::WaitableEvent event(false, false);
53856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink, FormatIsSet()).Times(1);
53956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Verify the sinks are getting the packets with an expecting buffer size.
54056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#if defined(OS_ANDROID)
54156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  const int expected_buffer_size = params.sample_rate() / 100;
54256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#else
54356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  const int expected_buffer_size = params.frames_per_buffer();
54456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
54556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*sink, CaptureData(
54656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      0, 0, 0, _, false))
54756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event));
54856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  track->AddSink(sink.get());
54956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
55056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_EQ(expected_buffer_size, sink->audio_params().frames_per_buffer());
55156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
55256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  // Stopping the new source will stop the second track.
55356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  EXPECT_CALL(*source, OnStop()).Times(1);
55456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks  capturer->Stop();
55556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
55656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
55756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}  // namespace content
55856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks