webrtc_local_audio_track_unittest.cc revision 58537e28ecd584eab876aee8be7156509866d23a
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"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/media/webrtc_local_audio_track.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/audio/audio_parameters.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/audio_bus.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/audio_capturer_source.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
15bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::_;
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using ::testing::AnyNumber;
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::AtLeast;
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::Return;
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace content {
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ACTION_P(SignalEvent, event) {
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  event->Signal();
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A simple thread that we use to fake the audio thread which provides data to
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the |WebRtcAudioCapturer|.
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class FakeAudioThread : public base::PlatformThread::Delegate {
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit FakeAudioThread(const scoped_refptr<WebRtcAudioCapturer>& capturer)
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : capturer_(capturer),
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      thread_(),
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      closure_(false, false) {
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(capturer.get());
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    audio_bus_ = media::AudioBus::Create(capturer_->audio_parameters());
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual ~FakeAudioThread() { DCHECK(thread_.is_null()); }
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // base::PlatformThread::Delegate:
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ThreadMain() OVERRIDE {
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    while (true) {
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (closure_.IsSignaled())
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      media::AudioCapturerSource::CaptureCallback* callback =
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          static_cast<media::AudioCapturerSource::CaptureCallback*>(
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              capturer_.get());
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      audio_bus_->Zero();
543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback->Capture(audio_bus_.get(), 0, 0, false);
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Sleep 1ms to yield the resource for the main thread.
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Start() {
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::PlatformThread::CreateWithPriority(
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        0, this, &thread_, base::kThreadPriority_RealtimeAudio);
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CHECK(!thread_.is_null());
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Stop() {
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    closure_.Signal();
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::PlatformThread::Join(thread_);
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    thread_ = base::PlatformThreadHandle();
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<media::AudioBus> audio_bus_;
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<WebRtcAudioCapturer> capturer_;
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::PlatformThreadHandle thread_;
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WaitableEvent closure_;
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeAudioThread);
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockCapturerSource : public media::AudioCapturerSource {
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockCapturerSource() {}
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD3(Initialize, void(const media::AudioParameters& params,
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                CaptureCallback* callback,
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                int session_id));
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD0(Start, void());
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD0(Stop, void());
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD1(SetVolume, void(double volume));
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD1(SetAutomaticGainControl, void(bool enable));
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~MockCapturerSource() {}
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockWebRtcAudioCapturerSink : public WebRtcAudioCapturerSink {
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockWebRtcAudioCapturerSink() {}
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ~MockWebRtcAudioCapturerSink() {}
100bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  int CaptureData(const std::vector<int>& channels,
101bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                  const int16* audio_data,
102bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                  int sample_rate,
103bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                  int number_of_channels,
104bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                  int number_of_frames,
105bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                  int audio_delay_milliseconds,
106bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                  int current_volume,
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                  bool need_audio_processing,
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                  bool key_pressed) OVERRIDE {
1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CaptureData(channels.size(),
1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                sample_rate,
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                number_of_channels,
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                number_of_frames,
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                audio_delay_milliseconds,
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                current_volume,
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                need_audio_processing,
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                key_pressed);
117bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return 0;
118bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MOCK_METHOD8(CaptureData,
1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)               void(int number_of_network_channels,
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    int sample_rate,
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    int number_of_channels,
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    int number_of_frames,
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    int audio_delay_milliseconds,
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    int current_volume,
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    bool need_audio_processing,
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    bool key_pressed));
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD1(SetCaptureFormat, void(const media::AudioParameters& params));
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class WebRtcLocalAudioTrackTest : public ::testing::Test {
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    capturer_ = WebRtcAudioCapturer::CreateCapturer();
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    capturer_source_ = new MockCapturerSource();
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_CALL(*capturer_source_.get(), Initialize(_, capturer_.get(), 0))
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        .WillOnce(Return());
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    capturer_->SetCapturerSource(capturer_source_,
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 media::CHANNEL_LAYOUT_STEREO,
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 48000);
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(false))
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        .WillOnce(Return());
146bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
147bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    // Start the audio thread used by the |capturer_source_|.
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    audio_thread_.reset(new FakeAudioThread(capturer_));
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    audio_thread_->Start();
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void TearDown() {
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    audio_thread_->Stop();
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    audio_thread_.reset();
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockCapturerSource> capturer_source_;
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<WebRtcAudioCapturer> capturer_;
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<FakeAudioThread> audio_thread_;
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Creates a capturer and audio track, fakes its audio thread, and
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// connect/disconnect the sink to the audio track on the fly, the sink should
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// get data callback when the track is connected to the capturer but not when
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the track is disconnected from the capturer.
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, ConnectAndDisconnectOneSink) {
1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return());
16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RTCMediaConstraints constraints;
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track =
17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL,
17158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &constraints);
1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track->Start();
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(track->enabled());
174bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
175bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Connect a number of network channels to the audio track.
176bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static const int kNumberOfNetworkChannels = 4;
177bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  for (int i = 0; i < kNumberOfNetworkChannels; ++i) {
178bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    static_cast<webrtc::AudioTrackInterface*>(track.get())->
179bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        GetRenderer()->AddChannel(i);
180bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<MockWebRtcAudioCapturerSink> sink(
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new MockWebRtcAudioCapturerSink());
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const media::AudioParameters params = capturer_->audio_parameters();
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WaitableEvent event(false, false);
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return());
1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink,
18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CaptureData(kNumberOfNetworkChannels,
18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.sample_rate(),
18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.channels(),
19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.frames_per_buffer(),
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false,
19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false)).Times(AtLeast(1))
1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(SignalEvent(&event));
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track->AddSink(sink.get());
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track->RemoveSink(sink.get());
2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return());
2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track->Stop();
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track = NULL;
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The same setup as ConnectAndDisconnectOneSink, but enable and disable the
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// audio track on the fly. When the audio track is disabled, there is no data
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// callback to the sink; when the audio track is enabled, there comes data
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// callback.
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TODO(xians): Enable this test after resolving the racing issue that TSAN
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// reports on MediaStreamTrack::enabled();
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, DISABLED_DisableEnableAudioTrack) {
2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return());
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RTCMediaConstraints constraints;
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track =
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL,
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        &constraints);
2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track->Start();
219bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static_cast<webrtc::AudioTrackInterface*>(track.get())->
220bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      GetRenderer()->AddChannel(0);
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(track->enabled());
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(track->set_enabled(false));
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<MockWebRtcAudioCapturerSink> sink(
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new MockWebRtcAudioCapturerSink());
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const media::AudioParameters params = capturer_->audio_parameters();
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WaitableEvent event(false, false);
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*sink, SetCaptureFormat(_)).WillOnce(Return());
2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink,
2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              CaptureData(1,
2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          params.sample_rate(),
2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          params.channels(),
2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          params.frames_per_buffer(),
2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          0,
2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          0,
2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          false,
2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          false)).Times(0);
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track->AddSink(sink.get());
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(event.TimedWait(TestTimeouts::tiny_timeout()));
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  event.Reset();
2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink,
2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              CaptureData(1,
2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          params.sample_rate(),
2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          params.channels(),
2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          params.frames_per_buffer(),
2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          0,
2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          0,
2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          false,
2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          false)).Times(AtLeast(1))
2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(SignalEvent(&event));
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(track->set_enabled(true));
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track->RemoveSink(sink.get());
2547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return());
2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track->Stop();
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track = NULL;
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Create multiple audio tracks and enable/disable them, verify that the audio
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// callbacks appear/disappear.
2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, MultipleAudioTracks) {
2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(Return());
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RTCMediaConstraints constraints;
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track_1 =
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL,
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        &constraints);
2687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_1->Start();
269bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static_cast<webrtc::AudioTrackInterface*>(track_1.get())->
270bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      GetRenderer()->AddChannel(0);
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(track_1->enabled());
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<MockWebRtcAudioCapturerSink> sink_1(
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new MockWebRtcAudioCapturerSink());
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const media::AudioParameters params = capturer_->audio_parameters();
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WaitableEvent event_1(false, false);
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*sink_1, SetCaptureFormat(_)).WillOnce(Return());
2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink_1,
27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CaptureData(1,
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.sample_rate(),
28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.channels(),
28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.frames_per_buffer(),
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false,
28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false)).Times(AtLeast(1))
2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(SignalEvent(&event_1));
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track_1->AddSink(sink_1.get());
2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout()));
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track_2 =
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL,
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        &constraints);
2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_2->Start();
294bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static_cast<webrtc::AudioTrackInterface*>(track_2.get())->
295bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      GetRenderer()->AddChannel(1);
2967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(track_2->enabled());
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Verify both |sink_1| and |sink_2| get data.
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  event_1.Reset();
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WaitableEvent event_2(false, false);
3017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<MockWebRtcAudioCapturerSink> sink_2(
3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        new MockWebRtcAudioCapturerSink());
3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*sink_2, SetCaptureFormat(_)).WillOnce(Return());
3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink_1,
30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CaptureData(1,
30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.sample_rate(),
30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.channels(),
30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.frames_per_buffer(),
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false,
31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false)).Times(AtLeast(1))
3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(SignalEvent(&event_1));
3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink_2,
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CaptureData(1,
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.sample_rate(),
31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.channels(),
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  params.frames_per_buffer(),
32058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  0,
32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false,
32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  false)).Times(AtLeast(1))
3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(SignalEvent(&event_2));
3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_2->AddSink(sink_2.get());
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(event_1.TimedWait(TestTimeouts::tiny_timeout()));
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(event_2.TimedWait(TestTimeouts::tiny_timeout()));
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track_1->RemoveSink(sink_1.get());
3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_1->Stop();
3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_1 = NULL;
3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), Stop()).WillOnce(Return());
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track_2->RemoveSink(sink_2.get());
3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_2->Stop();
3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_2 = NULL;
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Start one track and verify the capturer is correctly starting its source.
3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// And it should be fine to not to call Stop() explicitly.
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, StartOneAudioTrack) {
3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), Start()).Times(1);
34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RTCMediaConstraints constraints;
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track =
34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL,
34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &constraints);
3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track->Start();
3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // When the track goes away, it will automatically stop the
3517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // |capturer_source_|.
3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), Stop());
353bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track->Stop();
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track = NULL;
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Start/Stop tracks and verify the capturer is correctly starting/stopping
3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// its source.
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, StartAndStopAudioTracks) {
3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Starting the first audio track will start the |capturer_source_|.
361bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  base::WaitableEvent event(false, false);
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), Start()).WillOnce(SignalEvent(&event));
36358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RTCMediaConstraints constraints;
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track_1 =
36558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL,
36658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &constraints);
367bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static_cast<webrtc::AudioTrackInterface*>(track_1.get())->
368bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      GetRenderer()->AddChannel(0);
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_1->Start();
3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
372bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Verify the data flow by connecting the sink to |track_1|.
373bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_ptr<MockWebRtcAudioCapturerSink> sink(
374bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      new MockWebRtcAudioCapturerSink());
375bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  event.Reset();
3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink, CaptureData(_, _, _, _, 0, 0, false, false))
377bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      .Times(AnyNumber()).WillRepeatedly(Return());
378bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_CALL(*sink, SetCaptureFormat(_)).Times(1);
379bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_1->AddSink(sink.get());
380bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Start the second audio track will not start the |capturer_source_|
3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // since it has been started.
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), Start()).Times(0);
3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track_2 =
38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL,
38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &constraints);
3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_2->Start();
388bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static_cast<webrtc::AudioTrackInterface*>(track_2.get())->
389bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      GetRenderer()->AddChannel(1);
3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Stop the first audio track will not stop the |capturer_source_|.
3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), Stop()).Times(0);
393bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_1->RemoveSink(sink.get());
3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_1->Stop();
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track_1 = NULL;
3967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(*sink, CaptureData(_, _, _, _, 0, 0, false, false))
398bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      .Times(AnyNumber()).WillRepeatedly(Return());
399bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_CALL(*sink, SetCaptureFormat(_)).Times(1);
400bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_2->AddSink(sink.get());
401bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Stop the last audio track will stop the |capturer_source_|.
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  event.Reset();
4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), Stop())
4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      .Times(1).WillOnce(SignalEvent(&event));
4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track_2->Stop();
407bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_2->RemoveSink(sink.get());
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  track_2 = NULL;
4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
412bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Set new source to the existing capturer.
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WebRtcLocalAudioTrackTest, SetNewSourceForCapturerAfterStartTrack) {
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Setup the audio track and start the track.
4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), Start()).Times(1);
41658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RTCMediaConstraints constraints;
4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<WebRtcLocalAudioTrack> track =
41858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL,
41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &constraints);
4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track->Start();
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Setting new source to the capturer and the track should still get packets.
4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<MockCapturerSource> new_source(new MockCapturerSource());
4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*capturer_source_.get(), Stop());
4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*new_source.get(), SetAutomaticGainControl(false));
4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*new_source.get(), Initialize(_, capturer_.get(), 0))
4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      .WillOnce(Return());
4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*new_source.get(), Start()).WillOnce(Return());
4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  capturer_->SetCapturerSource(new_source,
4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               media::CHANNEL_LAYOUT_STEREO,
4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               48000);
4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Stop the track.
4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*new_source.get(), Stop());
4357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track->Stop();
4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  track = NULL;
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
439bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Create a new capturer with new source, connect it to a new audio track.
440bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochTEST_F(WebRtcLocalAudioTrackTest, ConnectTracksToDifferentCapturers) {
441bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Setup the first audio track and start it.
442bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_CALL(*capturer_source_.get(), Start()).Times(1);
44358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  RTCMediaConstraints constraints;
444bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<WebRtcLocalAudioTrack> track_1 =
44558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), capturer_, NULL,
44658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &constraints);
447bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_1->Start();
448bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
449bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Connect a number of network channels to the |track_1|.
450bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static const int kNumberOfNetworkChannelsForTrack1 = 2;
451bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  for (int i = 0; i < kNumberOfNetworkChannelsForTrack1; ++i) {
452bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    static_cast<webrtc::AudioTrackInterface*>(track_1.get())->
453bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        GetRenderer()->AddChannel(i);
454bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
455bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Verify the data flow by connecting the |sink_1| to |track_1|.
456bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_ptr<MockWebRtcAudioCapturerSink> sink_1(
457bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      new MockWebRtcAudioCapturerSink());
4583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(
4593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      *sink_1.get(),
4603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      CaptureData(
4613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          kNumberOfNetworkChannelsForTrack1, 48000, 2, _, 0, 0, false, false))
462bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      .Times(AnyNumber()).WillRepeatedly(Return());
463bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_CALL(*sink_1.get(), SetCaptureFormat(_)).Times(1);
464bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_1->AddSink(sink_1.get());
465bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
466bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Create a new capturer with new source with different audio format.
467bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<WebRtcAudioCapturer> new_capturer(
468bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      WebRtcAudioCapturer::CreateCapturer());
469bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<MockCapturerSource> new_source(new MockCapturerSource());
470bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_CALL(*new_source.get(), Initialize(_, new_capturer.get(), 0))
471bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      .WillOnce(Return());
472bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_CALL(*new_source.get(), SetAutomaticGainControl(false))
473bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      .WillOnce(Return());
474bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  new_capturer->SetCapturerSource(new_source,
475bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                  media::CHANNEL_LAYOUT_MONO,
476bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                  44100);
477bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
478bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Start the audio thread used by the new source.
479bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_ptr<FakeAudioThread> audio_thread(new FakeAudioThread(new_capturer));
480bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  audio_thread->Start();
481bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
482bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Setup the second audio track, connect it to the new capturer and start it.
483bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_CALL(*new_source.get(), Start()).Times(1);
484bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_refptr<WebRtcLocalAudioTrack> track_2 =
48558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      WebRtcLocalAudioTrack::Create(std::string(), new_capturer, NULL,
48658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          &constraints);
487bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_2->Start();
488bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
489bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Connect a number of network channels to the |track_2|.
490bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static const int kNumberOfNetworkChannelsForTrack2 = 3;
491bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  for (int i = 0; i < kNumberOfNetworkChannelsForTrack2; ++i) {
492bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    static_cast<webrtc::AudioTrackInterface*>(track_2.get())->
493bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        GetRenderer()->AddChannel(i);
494bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
495bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Verify the data flow by connecting the |sink_2| to |track_2|.
496bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  scoped_ptr<MockWebRtcAudioCapturerSink> sink_2(
497bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      new MockWebRtcAudioCapturerSink());
4983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(
4993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      *sink_2,
5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      CaptureData(
5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          kNumberOfNetworkChannelsForTrack2, 44100, 1, _, 0, 0, false, false))
502bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      .Times(AnyNumber()).WillRepeatedly(Return());
503bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_CALL(*sink_2, SetCaptureFormat(_)).Times(1);
504bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_2->AddSink(sink_2.get());
505bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
506bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Stop the second audio track will stop the new source.
507bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  base::WaitableEvent event(false, false);
508bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_CALL(*new_source.get(), Stop()).Times(1).WillOnce(SignalEvent(&event));
509bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_2->Stop();
510bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_2->RemoveSink(sink_2.get());
511bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_2 = NULL;
512bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_TRUE(event.TimedWait(TestTimeouts::tiny_timeout()));
513bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  audio_thread->Stop();
514bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  audio_thread.reset();
515bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
516bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Stop the first audio track.
517bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_CALL(*capturer_source_.get(), Stop());
518bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_1->Stop();
519bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  track_1 = NULL;
520bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
521bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace content
523