webrtc_local_audio_track_unittest.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/synchronization/waitable_event.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/test/test_timeouts.h"
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/renderer/media/rtc_media_constraints.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/media/webrtc_audio_capturer.h"
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/renderer/media/webrtc_audio_device_impl.h"
10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/renderer/media/webrtc_local_audio_source_provider.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/media/webrtc_local_audio_track.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/audio/audio_parameters.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/audio_bus.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/audio_capturer_source.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
17bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::_;
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using ::testing::AnyNumber;
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::AtLeast;
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::Return;
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace content {
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ACTION_P(SignalEvent, event) {
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  event->Signal();
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A simple thread that we use to fake the audio thread which provides data to
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the |WebRtcAudioCapturer|.
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class FakeAudioThread : public base::PlatformThread::Delegate {
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FakeAudioThread(const scoped_refptr<WebRtcAudioCapturer>& capturer,
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  const media::AudioParameters& params)
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : capturer_(capturer),
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      thread_(),
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      closure_(false, false) {
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(capturer.get());
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    audio_bus_ = media::AudioBus::Create(params);
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual ~FakeAudioThread() { DCHECK(thread_.is_null()); }
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // base::PlatformThread::Delegate:
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ThreadMain() OVERRIDE {
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    while (true) {
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (closure_.IsSignaled())
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      media::AudioCapturerSource::CaptureCallback* callback =
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          static_cast<media::AudioCapturerSource::CaptureCallback*>(
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              capturer_.get());
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      audio_bus_->Zero();
573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback->Capture(audio_bus_.get(), 0, 0, false);
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Sleep 1ms to yield the resource for the main thread.
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Start() {
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::PlatformThread::CreateWithPriority(
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        0, this, &thread_, base::kThreadPriority_RealtimeAudio);
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CHECK(!thread_.is_null());
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Stop() {
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    closure_.Signal();
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::PlatformThread::Join(thread_);
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    thread_ = base::PlatformThreadHandle();
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<media::AudioBus> audio_bus_;
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<WebRtcAudioCapturer> capturer_;
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::PlatformThreadHandle thread_;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WaitableEvent closure_;
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeAudioThread);
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockCapturerSource : public media::AudioCapturerSource {
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  explicit MockCapturerSource(WebRtcAudioCapturer* capturer)
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : capturer_(capturer) {}
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MOCK_METHOD3(OnInitialize, void(const media::AudioParameters& params,
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  CaptureCallback* callback,
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  int session_id));
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MOCK_METHOD0(OnStart, void());
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MOCK_METHOD0(OnStop, void());
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD1(SetVolume, void(double volume));
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD1(SetAutomaticGainControl, void(bool enable));
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void Initialize(const media::AudioParameters& params,
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          CaptureCallback* callback,
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          int session_id) OVERRIDE {
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(params.IsValid());
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    params_ = params;
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    OnInitialize(params, callback, session_id);
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void Start() OVERRIDE {
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    audio_thread_.reset(new FakeAudioThread(capturer_, params_));
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    audio_thread_->Start();
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    OnStart();
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void Stop() OVERRIDE {
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    audio_thread_->Stop();
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    audio_thread_.reset();
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    OnStop();
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~MockCapturerSource() {}
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<FakeAudioThread> audio_thread_;
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WebRtcAudioCapturer* capturer_;
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  media::AudioParameters params_;
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// TODO(xians): Use MediaStreamAudioSink.
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class MockMediaStreamAudioSink : public PeerConnectionAudioSink {
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MockMediaStreamAudioSink() {}
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ~MockMediaStreamAudioSink() {}
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int OnData(const int16* audio_data,
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             int sample_rate,
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             int number_of_channels,
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             int number_of_frames,
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             const std::vector<int>& channels,
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             int audio_delay_milliseconds,
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             int current_volume,
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             bool need_audio_processing,
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             bool key_pressed) OVERRIDE {
1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CaptureData(channels.size(),
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                sample_rate,
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                number_of_channels,
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                number_of_frames,
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                audio_delay_milliseconds,
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                current_volume,
1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                need_audio_processing,
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                key_pressed);
144bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return 0;
145bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MOCK_METHOD8(CaptureData,
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)               void(int number_of_network_channels,
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    int sample_rate,
1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    int number_of_channels,
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    int number_of_frames,
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    int audio_delay_milliseconds,
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    int current_volume,
1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    bool need_audio_processing,
1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    bool key_pressed));
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD1(OnSetFormat, void(const media::AudioParameters& params));
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class WebRtcLocalAudioTrackTest : public ::testing::Test {
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                  media::CHANNEL_LAYOUT_STEREO, 2, 0, 48000, 16, 480);
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    capturer_ = WebRtcAudioCapturer::CreateCapturer();
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    capturer_source_ = new MockCapturerSource(capturer_.get());
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*capturer_source_.get(), OnInitialize(_, capturer_.get(), 0))
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        .WillOnce(Return());
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    capturer_->SetCapturerSource(capturer_source_,
170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                 params_.channel_layout(),
171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                 params_.sample_rate());
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  media::AudioParameters params_;
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockCapturerSource> capturer_source_;
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<WebRtcAudioCapturer> capturer_;
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Creates a capturer and audio track, fakes its audio thread, and
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// connect/disconnect the sink to the audio track on the fly, the sink should
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// get data callback when the track is connected to the capturer but not when
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the track is disconnected from the capturer.
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, ConnectAndDisconnectOneSink) {
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStart());
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RTCMediaConstraints constraints;
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track =
188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL,
18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &constraints);
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static_cast<WebRtcLocalAudioSourceProvider*>(
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      track->audio_source_provider())->SetSinkParamsForTesting(params_);
1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track->Start();
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(track->enabled());
194bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
195bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Connect a number of network channels to the audio track.
196bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static const int kNumberOfNetworkChannels = 4;
197bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  for (int i = 0; i < kNumberOfNetworkChannels; ++i) {
198bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    static_cast<webrtc::AudioTrackInterface*>(track.get())->
199bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        GetRenderer()->AddChannel(i);
200bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink());
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const media::AudioParameters params = capturer_->audio_parameters();
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WaitableEvent event(false, false);
204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(*sink, OnSetFormat(_)).WillOnce(Return());
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink,
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CaptureData(kNumberOfNetworkChannels,
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.sample_rate(),
20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.channels(),
209d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                  params.sample_rate() / 100,
21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false,
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false)).Times(AtLeast(1))
2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(SignalEvent(&event));
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track->AddSink(sink.get());
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track->RemoveSink(sink.get());
2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return());
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capturer_->Stop();
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The same setup as ConnectAndDisconnectOneSink, but enable and disable the
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// audio track on the fly. When the audio track is disabled, there is no data
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// callback to the sink; when the audio track is enabled, there comes data
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// callback.
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TODO(xians): Enable this test after resolving the racing issue that TSAN
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// reports on MediaStreamTrack::enabled();
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest,  DISABLED_DisableEnableAudioTrack) {
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStart());
23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RTCMediaConstraints constraints;
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track =
235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL,
23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        &constraints);
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static_cast<WebRtcLocalAudioSourceProvider*>(
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      track->audio_source_provider())->SetSinkParamsForTesting(params_);
2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track->Start();
240bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static_cast<webrtc::AudioTrackInterface*>(track.get())->
241bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      GetRenderer()->AddChannel(0);
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(track->enabled());
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(track->set_enabled(false));
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink());
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const media::AudioParameters params = capturer_->audio_parameters();
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WaitableEvent event(false, false);
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(*sink, OnSetFormat(_)).Times(1);
2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink,
2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              CaptureData(1,
2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          params.sample_rate(),
2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          params.channels(),
252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          params.sample_rate() / 100,
2533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          0,
2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          0,
2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          false,
2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          false)).Times(0);
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track->AddSink(sink.get());
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout()));
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  event.Reset();
2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink,
2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              CaptureData(1,
2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          params.sample_rate(),
2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          params.channels(),
265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          params.sample_rate() / 100,
2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          0,
2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          0,
2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          false,
2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          false)).Times(AtLeast(1))
2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(SignalEvent(&event));
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(track->set_enabled(true));
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track->RemoveSink(sink.get());
2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return());
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capturer_->Stop();
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track = NULL;
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create multiple audio tracks and enable/disable them, verify that the audio
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// callbacks appear/disappear.
28268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Flaky due to a data race, see http://crbug.com/295418
28368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, DISABLED_MultipleAudioTracks) {
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStart());
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RTCMediaConstraints constraints;
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track_1 =
288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL,
28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        &constraints);
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static_cast<WebRtcLocalAudioSourceProvider*>(
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      track_1->audio_source_provider())->SetSinkParamsForTesting(params_);
2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_1->Start();
293bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static_cast<webrtc::AudioTrackInterface*>(track_1.get())->
294bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      GetRenderer()->AddChannel(0);
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(track_1->enabled());
296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<MockMediaStreamAudioSink> sink_1(new MockMediaStreamAudioSink());
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const media::AudioParameters params = capturer_->audio_parameters();
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WaitableEvent event_1(false, false);
299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(*sink_1, OnSetFormat(_)).WillOnce(Return());
3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink_1,
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CaptureData(1,
30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.sample_rate(),
30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.channels(),
304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                  params.sample_rate() / 100,
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false,
30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false)).Times(AtLeast(1))
3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(SignalEvent(&event_1));
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track_1->AddSink(sink_1.get());
3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout()));
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track_2 =
314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL,
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        &constraints);
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static_cast<WebRtcLocalAudioSourceProvider*>(
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      track_2->audio_source_provider())->SetSinkParamsForTesting(params_);
3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_2->Start();
319bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static_cast<webrtc::AudioTrackInterface*>(track_2.get())->
320bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      GetRenderer()->AddChannel(1);
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(track_2->enabled());
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Verify both |sink_1| and |sink_2| get data.
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  event_1.Reset();
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WaitableEvent event_2(false, false);
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<MockMediaStreamAudioSink> sink_2(new MockMediaStreamAudioSink());
328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(*sink_2, OnSetFormat(_)).WillOnce(Return());
3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink_1,
33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CaptureData(1,
33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.sample_rate(),
33258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.channels(),
333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                  params.sample_rate() / 100,
33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
33558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
33658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false,
33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false)).Times(AtLeast(1))
3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(SignalEvent(&event_1));
3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink_2,
34058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CaptureData(1,
34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.sample_rate(),
34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.channels(),
343d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                  params.sample_rate() / 100,
34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false,
34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false)).Times(AtLeast(1))
3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(SignalEvent(&event_2));
3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_2->AddSink(sink_2.get());
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout()));
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout()));
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track_1->RemoveSink(sink_1.get());
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_1->Stop();
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_1 = NULL;
3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStop()).WillOnce(Return());
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track_2->RemoveSink(sink_2.get());
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_2->Stop();
3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_2 = NULL;
361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capturer_->Stop();
3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Start one track and verify the capturer is correctly starting its source.
3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// And it should be fine to not to call Stop() explicitly.
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, StartOneAudioTrack) {
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStart());
37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RTCMediaConstraints constraints;
3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track =
373d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL,
37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &constraints);
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static_cast<WebRtcLocalAudioSourceProvider*>(
376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      track->audio_source_provider())->SetSinkParamsForTesting(params_);
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track->Start();
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // When the track goes away, it will automatically stop the
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // |capturer_source_|.
381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStop());
382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capturer_->Stop();
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track = NULL;
3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Start/Stop tracks and verify the capturer is correctly starting/stopping
3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// its source.
3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, StartAndStopAudioTracks) {
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Starting the first audio track will start the |capturer_source_|.
390bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  base::WaitableEvent event(false, false);
391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStart()).WillOnce(SignalEvent(&event));
39358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RTCMediaConstraints constraints;
3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track_1 =
395d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL,
39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &constraints);
397bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static_cast<webrtc::AudioTrackInterface*>(track_1.get())->
398bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      GetRenderer()->AddChannel(0);
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static_cast<WebRtcLocalAudioSourceProvider*>(
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      track_1->audio_source_provider())->SetSinkParamsForTesting(params_);
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_1->Start();
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
404bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Verify the data flow by connecting the sink to |track_1|.
405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink());
406bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  event.Reset();
407a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(*sink, OnSetFormat(_)).WillOnce(SignalEvent(&event));
4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink, CaptureData(_, _, _, _, 0, 0, false, false))
409bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      .Times(AnyNumber()).WillRepeatedly(Return());
410bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_1->AddSink(sink.get());
411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
412bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Start the second audio track will not start the |capturer_source_|
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // since it has been started.
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStart()).Times(0);
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track_2 =
417d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL,
41858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &constraints);
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static_cast<WebRtcLocalAudioSourceProvider*>(
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      track_2->audio_source_provider())->SetSinkParamsForTesting(params_);
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_2->Start();
422bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static_cast<webrtc::AudioTrackInterface*>(track_2.get())->
423bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      GetRenderer()->AddChannel(1);
4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Stop the capturer will clear up the track lists in the capturer.
426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStop());
427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capturer_->Stop();
4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Adding a new track to the capturer.
430bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_2->AddSink(sink.get());
431a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(*sink, OnSetFormat(_)).Times(0);
432bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Stop the capturer again will not trigger stopping the source of the
434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // capturer again..
4357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  event.Reset();
436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStop()).Times(0);
437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capturer_->Stop();
4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
440bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Set new source to the existing capturer.
4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, SetNewSourceForCapturerAfterStartTrack) {
4427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Setup the audio track and start the track.
443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStart());
44558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RTCMediaConstraints constraints;
4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track =
447d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL,
44858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &constraints);
449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static_cast<WebRtcLocalAudioSourceProvider*>(
450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      track->audio_source_provider())->SetSinkParamsForTesting(params_);
4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track->Start();
4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Setting new source to the capturer and the track should still get packets.
454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<MockCapturerSource> new_source(
455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new MockCapturerSource(capturer_.get()));
456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStop());
4570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_CALL(*new_source.get(), SetAutomaticGainControl(true));
458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*new_source.get(), OnInitialize(_, capturer_.get(), 0))
4597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      .WillOnce(Return());
460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*new_source.get(), OnStart());
4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  capturer_->SetCapturerSource(new_source,
462d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                               params_.channel_layout(),
463d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                               params_.sample_rate());
4647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Stop the track.
466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*new_source.get(), OnStop());
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capturer_->Stop();
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
470bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Create a new capturer with new source, connect it to a new audio track.
471bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(WebRtcLocalAudioTrackTest, ConnectTracksToDifferentCapturers) {
472bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Setup the first audio track and start it.
473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStart());
47558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RTCMediaConstraints constraints;
476bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<WebRtcLocalAudioTrack> track_1 =
477d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL, NULL,
47858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &constraints);
479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static_cast<WebRtcLocalAudioSourceProvider*>(
480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      track_1->audio_source_provider())->SetSinkParamsForTesting(params_);
481bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_1->Start();
482bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
483bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Connect a number of network channels to the |track_1|.
484bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static const int kNumberOfNetworkChannelsForTrack1 = 2;
485bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  for (int i = 0; i < kNumberOfNetworkChannelsForTrack1; ++i) {
486bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    static_cast<webrtc::AudioTrackInterface*>(track_1.get())->
487bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        GetRenderer()->AddChannel(i);
488bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
489bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Verify the data flow by connecting the |sink_1| to |track_1|.
490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<MockMediaStreamAudioSink> sink_1(new MockMediaStreamAudioSink());
4913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(
4923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      *sink_1.get(),
4933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      CaptureData(
4943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          kNumberOfNetworkChannelsForTrack1, 48000, 2, _, 0, 0, false, false))
495bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      .Times(AnyNumber()).WillRepeatedly(Return());
496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(*sink_1.get(), OnSetFormat(_)).Times(AnyNumber());
497bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_1->AddSink(sink_1.get());
498bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
499bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Create a new capturer with new source with different audio format.
500bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<WebRtcAudioCapturer> new_capturer(
501bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      WebRtcAudioCapturer::CreateCapturer());
502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<MockCapturerSource> new_source(
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new MockCapturerSource(new_capturer.get()));
504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*new_source.get(), OnInitialize(_, new_capturer.get(), 0));
505bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  new_capturer->SetCapturerSource(new_source,
506bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                  media::CHANNEL_LAYOUT_MONO,
507bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                  44100);
508bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
509bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Setup the second audio track, connect it to the new capturer and start it.
510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*new_source.get(), SetAutomaticGainControl(true));
511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*new_source.get(), OnStart());
512bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<WebRtcLocalAudioTrack> track_2 =
513d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), new_capturer, NULL, NULL,
51458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &constraints);
515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static_cast<WebRtcLocalAudioSourceProvider*>(
516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      track_2->audio_source_provider())->SetSinkParamsForTesting(params_);
517bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_2->Start();
518bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
519bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Connect a number of network channels to the |track_2|.
520bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static const int kNumberOfNetworkChannelsForTrack2 = 3;
521bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  for (int i = 0; i < kNumberOfNetworkChannelsForTrack2; ++i) {
522bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    static_cast<webrtc::AudioTrackInterface*>(track_2.get())->
523bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        GetRenderer()->AddChannel(i);
524bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
525bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Verify the data flow by connecting the |sink_2| to |track_2|.
526a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<MockMediaStreamAudioSink> sink_2(new MockMediaStreamAudioSink());
527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::WaitableEvent event(false, false);
5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(
5293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      *sink_2,
5303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      CaptureData(
5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          kNumberOfNetworkChannelsForTrack2, 44100, 1, _, 0, 0, false, false))
532bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      .Times(AnyNumber()).WillRepeatedly(Return());
533a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(*sink_2, OnSetFormat(_)).WillOnce(SignalEvent(&event));
534bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_2->AddSink(sink_2.get());
535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Stopping the new source will stop the second track.
538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  event.Reset();
539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*new_source.get(), OnStop())
540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .Times(1).WillOnce(SignalEvent(&event));
541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  new_capturer->Stop();
542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Stop the capturer of the first audio track.
545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), OnStop());
546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capturer_->Stop();
547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
549bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Make sure a audio track can deliver packets with a buffer size smaller than
551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 10ms when it is not connected with a peer connection.
552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, TrackWorkWithSmallBufferSize) {
553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Setup a capturer which works with a buffer size smaller than 10ms.
554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                media::CHANNEL_LAYOUT_STEREO, 48000, 16, 128);
556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create a capturer with new source which works with the format above.
558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<WebRtcAudioCapturer> capturer(
559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      WebRtcAudioCapturer::CreateCapturer());
560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<MockCapturerSource> source(
561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new MockCapturerSource(capturer.get()));
562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capturer->Initialize(-1, params.channel_layout(), params.sample_rate(),
563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       params.frames_per_buffer(), 0, std::string(), 0, 0);
564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*source.get(), OnInitialize(_, capturer.get(), 0));
566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capturer->SetCapturerSource(source, params.channel_layout(),
567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              params.sample_rate());
568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Setup a audio track, connect it to the capturer and start it.
570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*source.get(), SetAutomaticGainControl(true));
571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*source.get(), OnStart());
572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RTCMediaConstraints constraints;
573f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track =
574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), capturer, NULL, NULL,
575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    &constraints);
576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static_cast<WebRtcLocalAudioSourceProvider*>(
577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      track->audio_source_provider())->SetSinkParamsForTesting(params);
578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  track->Start();
579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Verify the data flow by connecting the |sink| to |track|.
581a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<MockMediaStreamAudioSink> sink(new MockMediaStreamAudioSink());
582bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  base::WaitableEvent event(false, false);
583a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(*sink, OnSetFormat(_)).Times(1);
584f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Verify the sinks are getting the packets with an expecting buffer size.
585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_ANDROID)
586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int expected_buffer_size = params.sample_rate() / 100;
587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else
588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int expected_buffer_size = params.frames_per_buffer();
589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*sink, CaptureData(
591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      0, params.sample_rate(), params.channels(), expected_buffer_size,
592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      0, 0, false, false))
593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .Times(AtLeast(1)).WillRepeatedly(SignalEvent(&event));
594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  track->AddSink(sink.get());
595bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
596bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Stopping the new source will stop the second track.
598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*source, OnStop()).Times(1);
599f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capturer->Stop();
600bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
601bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace content
603