| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/media/webrtc_audio_renderer.h" | 5 #include "content/renderer/media/webrtc_audio_renderer.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
| 13 #include "build/build_config.h" | 13 #include "build/build_config.h" |
| 14 #include "content/public/renderer/media_stream_audio_renderer.h" | 14 #include "content/public/renderer/media_stream_audio_renderer.h" |
| 15 #include "content/renderer/media/audio_device_factory.h" | 15 #include "content/renderer/media/audio_device_factory.h" |
| 16 #include "content/renderer/media/webrtc_audio_device_impl.h" | 16 #include "content/renderer/media/webrtc_audio_device_impl.h" |
| 17 #include "media/base/audio_renderer_sink.h" | 17 #include "media/base/mock_audio_renderer_sink.h" |
| 18 #include "media/base/output_device.h" | |
| 19 #include "testing/gmock/include/gmock/gmock.h" | 18 #include "testing/gmock/include/gmock/gmock.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 21 #include "third_party/WebKit/public/platform/WebMediaStream.h" | 20 #include "third_party/WebKit/public/platform/WebMediaStream.h" |
| 22 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" | 21 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" |
| 23 #include "third_party/WebKit/public/web/WebHeap.h" | 22 #include "third_party/WebKit/public/web/WebHeap.h" |
| 24 #include "third_party/webrtc/api/mediastreaminterface.h" | 23 #include "third_party/webrtc/api/mediastreaminterface.h" |
| 25 | 24 |
| 26 using testing::Return; | 25 using testing::Return; |
| 27 using testing::_; | 26 using testing::_; |
| 28 | 27 |
| 29 namespace content { | 28 namespace content { |
| 30 | 29 |
| 31 namespace { | 30 namespace { |
| 32 | 31 |
| 33 const int kHardwareSampleRate = 44100; | 32 const int kHardwareSampleRate = 44100; |
| 34 const int kHardwareBufferSize = 512; | 33 const int kHardwareBufferSize = 512; |
| 35 const char kDefaultOutputDeviceId[] = ""; | 34 const char kDefaultOutputDeviceId[] = ""; |
| 36 const char kOtherOutputDeviceId[] = "other-output-device"; | 35 const char kOtherOutputDeviceId[] = "other-output-device"; |
| 37 const char kInvalidOutputDeviceId[] = "invalid-device"; | 36 const char kInvalidOutputDeviceId[] = "invalid-device"; |
| 38 | 37 |
| 39 class FakeAudioOutputDevice | |
| 40 : NON_EXPORTED_BASE(public media::AudioRendererSink), | |
| 41 NON_EXPORTED_BASE(public media::OutputDevice) { | |
| 42 public: | |
| 43 FakeAudioOutputDevice(const std::string& device_id) : device_id_(device_id) {} | |
| 44 MOCK_METHOD2(Initialize, | |
| 45 void(const media::AudioParameters&, RenderCallback*)); | |
| 46 MOCK_METHOD0(Start, void()); | |
| 47 MOCK_METHOD0(Stop, void()); | |
| 48 MOCK_METHOD0(Pause, void()); | |
| 49 MOCK_METHOD0(Play, void()); | |
| 50 MOCK_METHOD1(SetVolume, bool(double volume)); | |
| 51 OutputDevice* GetOutputDevice() { return this; } | |
| 52 MOCK_METHOD3(SwitchOutputDevice, | |
| 53 void(const std::string&, | |
| 54 const url::Origin&, | |
| 55 const media::SwitchOutputDeviceCB&)); | |
| 56 | |
| 57 media::OutputDeviceStatus GetDeviceStatus() override { | |
| 58 return device_id_ == kInvalidOutputDeviceId | |
| 59 ? media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL | |
| 60 : media::OUTPUT_DEVICE_STATUS_OK; | |
| 61 } | |
| 62 | |
| 63 std::string GetDeviceId() const { return device_id_; } | |
| 64 | |
| 65 media::AudioParameters GetOutputParameters() override { | |
| 66 return media::AudioParameters(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, | |
| 67 media::CHANNEL_LAYOUT_STEREO, | |
| 68 kHardwareSampleRate, 16, kHardwareBufferSize); | |
| 69 } | |
| 70 | |
| 71 protected: | |
| 72 virtual ~FakeAudioOutputDevice() {} | |
| 73 | |
| 74 private: | |
| 75 const std::string device_id_; | |
| 76 }; | |
| 77 | |
| 78 class MockAudioRendererSource : public WebRtcAudioRendererSource { | 38 class MockAudioRendererSource : public WebRtcAudioRendererSource { |
| 79 public: | 39 public: |
| 80 MockAudioRendererSource() {} | 40 MockAudioRendererSource() {} |
| 81 virtual ~MockAudioRendererSource() {} | 41 virtual ~MockAudioRendererSource() {} |
| 82 MOCK_METHOD4(RenderData, void(media::AudioBus* audio_bus, | 42 MOCK_METHOD4(RenderData, void(media::AudioBus* audio_bus, |
| 83 int sample_rate, | 43 int sample_rate, |
| 84 int audio_delay_milliseconds, | 44 int audio_delay_milliseconds, |
| 85 base::TimeDelta* current_time)); | 45 base::TimeDelta* current_time)); |
| 86 MOCK_METHOD1(RemoveAudioRenderer, void(WebRtcAudioRenderer* renderer)); | 46 MOCK_METHOD1(RemoveAudioRenderer, void(WebRtcAudioRenderer* renderer)); |
| 87 MOCK_METHOD0(AudioRendererThreadStopped, void()); | 47 MOCK_METHOD0(AudioRendererThreadStopped, void()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 110 void SetupRenderer(const std::string& device_id) { | 70 void SetupRenderer(const std::string& device_id) { |
| 111 renderer_ = new WebRtcAudioRenderer(message_loop_->task_runner(), stream_, | 71 renderer_ = new WebRtcAudioRenderer(message_loop_->task_runner(), stream_, |
| 112 1, 1, device_id, url::Origin()); | 72 1, 1, device_id, url::Origin()); |
| 113 EXPECT_CALL( | 73 EXPECT_CALL( |
| 114 *this, MockCreateAudioRendererSink(AudioDeviceFactory::kSourceWebRtc, _, | 74 *this, MockCreateAudioRendererSink(AudioDeviceFactory::kSourceWebRtc, _, |
| 115 _, device_id, _)); | 75 _, device_id, _)); |
| 116 EXPECT_TRUE(renderer_->Initialize(source_.get())); | 76 EXPECT_TRUE(renderer_->Initialize(source_.get())); |
| 117 | 77 |
| 118 renderer_proxy_ = renderer_->CreateSharedAudioRendererProxy(stream_); | 78 renderer_proxy_ = renderer_->CreateSharedAudioRendererProxy(stream_); |
| 119 } | 79 } |
| 120 MOCK_METHOD1(CreateInputDevice, media::AudioInputDevice*(int)); | 80 MOCK_METHOD1(CreateInputDevice, scoped_refptr<media::AudioInputDevice>(int)); |
| 121 MOCK_METHOD4(CreateOutputDevice, | 81 MOCK_METHOD4(CreateAudioRendererMixerSink, |
| 122 media::AudioOutputDevice*(int, | 82 scoped_refptr<media::AudioRendererSink>(int, |
| 123 int, | 83 int, |
| 124 const std::string&, | 84 const std::string&, |
| 125 const url::Origin&)); | 85 const url::Origin&)); |
| 126 MOCK_METHOD5(CreateRestartableAudioRendererSink, | 86 MOCK_METHOD5( |
| 127 media::RestartableAudioRendererSink*(SourceType, | 87 CreateSwitchableAudioRendererSink, |
| 128 int, | 88 scoped_refptr<media::SwitchableAudioRendererSink>(SourceType, |
| 129 int, | 89 int, |
| 130 const std::string&, | 90 int, |
| 131 const url::Origin&)); | 91 const std::string&, |
| 132 MOCK_METHOD5(MockCreateAudioRendererSink, | 92 const url::Origin&)); |
| 133 media::AudioRendererSink*(SourceType, | 93 MOCK_METHOD5( |
| 134 int, | 94 MockCreateAudioRendererSink, |
| 135 int, | 95 void(SourceType, int, int, const std::string&, const url::Origin&)); |
| 136 const std::string&, | 96 |
| 137 const url::Origin&)); | 97 scoped_refptr<media::AudioRendererSink> CreateAudioRendererSink( |
| 138 media::AudioRendererSink* CreateAudioRendererSink( | |
| 139 SourceType source_type, | 98 SourceType source_type, |
| 140 int render_frame_id, | 99 int render_frame_id, |
| 141 int session_id, | 100 int session_id, |
| 142 const std::string& device_id, | 101 const std::string& device_id, |
| 143 const url::Origin& security_origin) { | 102 const url::Origin& security_origin) { |
| 144 FakeAudioOutputDevice* fake_device = new FakeAudioOutputDevice(device_id); | 103 scoped_refptr<media::MockAudioRendererSink> fake_sink( |
| 104 new media::MockAudioRendererSink( |
| 105 device_id, device_id == kInvalidOutputDeviceId |
| 106 ? media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL |
| 107 : media::OUTPUT_DEVICE_STATUS_OK, |
| 108 media::AudioParameters( |
| 109 media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| 110 media::CHANNEL_LAYOUT_STEREO, kHardwareSampleRate, 16, |
| 111 kHardwareBufferSize))); |
| 145 if (device_id != kInvalidOutputDeviceId) { | 112 if (device_id != kInvalidOutputDeviceId) { |
| 146 mock_output_device_ = fake_device; | 113 mock_sink_ = fake_sink; |
| 147 EXPECT_CALL(*mock_output_device_.get(), Start()); | 114 EXPECT_CALL(*mock_sink_.get(), Start()); |
| 148 } | 115 } |
| 149 | 116 |
| 150 MockCreateAudioRendererSink(source_type, render_frame_id, session_id, | 117 MockCreateAudioRendererSink(source_type, render_frame_id, session_id, |
| 151 device_id, security_origin); | 118 device_id, security_origin); |
| 152 return fake_device; | 119 return fake_sink; |
| 153 } | 120 } |
| 154 | 121 |
| 155 void TearDown() override { | 122 void TearDown() override { |
| 156 renderer_proxy_ = nullptr; | 123 renderer_proxy_ = nullptr; |
| 157 renderer_ = nullptr; | 124 renderer_ = nullptr; |
| 158 stream_.reset(); | 125 stream_.reset(); |
| 159 source_.reset(); | 126 source_.reset(); |
| 160 mock_output_device_ = nullptr; | 127 mock_sink_ = nullptr; |
| 161 blink::WebHeap::collectAllGarbageForTesting(); | 128 blink::WebHeap::collectAllGarbageForTesting(); |
| 162 } | 129 } |
| 163 | 130 |
| 164 scoped_ptr<base::MessageLoopForIO> message_loop_; | 131 scoped_ptr<base::MessageLoopForIO> message_loop_; |
| 165 scoped_refptr<FakeAudioOutputDevice> mock_output_device_; | 132 scoped_refptr<media::MockAudioRendererSink> mock_sink_; |
| 166 scoped_ptr<MockAudioRendererSource> source_; | 133 scoped_ptr<MockAudioRendererSource> source_; |
| 167 blink::WebMediaStream stream_; | 134 blink::WebMediaStream stream_; |
| 168 scoped_refptr<WebRtcAudioRenderer> renderer_; | 135 scoped_refptr<WebRtcAudioRenderer> renderer_; |
| 169 scoped_refptr<MediaStreamAudioRenderer> renderer_proxy_; | 136 scoped_refptr<MediaStreamAudioRenderer> renderer_proxy_; |
| 170 }; | 137 }; |
| 171 | 138 |
| 172 // Verify that the renderer will be stopped if the only proxy is stopped. | 139 // Verify that the renderer will be stopped if the only proxy is stopped. |
| 173 TEST_F(WebRtcAudioRendererTest, StopRenderer) { | 140 TEST_F(WebRtcAudioRendererTest, StopRenderer) { |
| 174 SetupRenderer(kDefaultOutputDeviceId); | 141 SetupRenderer(kDefaultOutputDeviceId); |
| 175 renderer_proxy_->Start(); | 142 renderer_proxy_->Start(); |
| 176 | 143 |
| 177 // |renderer_| has only one proxy, stopping the proxy should stop the sink of | 144 // |renderer_| has only one proxy, stopping the proxy should stop the sink of |
| 178 // |renderer_|. | 145 // |renderer_|. |
| 179 EXPECT_CALL(*mock_output_device_.get(), Stop()); | 146 EXPECT_CALL(*mock_sink_.get(), Stop()); |
| 180 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); | 147 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); |
| 181 renderer_proxy_->Stop(); | 148 renderer_proxy_->Stop(); |
| 182 } | 149 } |
| 183 | 150 |
| 184 // Verify that the renderer will not be stopped unless the last proxy is | 151 // Verify that the renderer will not be stopped unless the last proxy is |
| 185 // stopped. | 152 // stopped. |
| 186 TEST_F(WebRtcAudioRendererTest, MultipleRenderers) { | 153 TEST_F(WebRtcAudioRendererTest, MultipleRenderers) { |
| 187 SetupRenderer(kDefaultOutputDeviceId); | 154 SetupRenderer(kDefaultOutputDeviceId); |
| 188 renderer_proxy_->Start(); | 155 renderer_proxy_->Start(); |
| 189 | 156 |
| 190 // Create a vector of renderer proxies from the |renderer_|. | 157 // Create a vector of renderer proxies from the |renderer_|. |
| 191 std::vector<scoped_refptr<MediaStreamAudioRenderer> > renderer_proxies_; | 158 std::vector<scoped_refptr<MediaStreamAudioRenderer> > renderer_proxies_; |
| 192 static const int kNumberOfRendererProxy = 5; | 159 static const int kNumberOfRendererProxy = 5; |
| 193 for (int i = 0; i < kNumberOfRendererProxy; ++i) { | 160 for (int i = 0; i < kNumberOfRendererProxy; ++i) { |
| 194 scoped_refptr<MediaStreamAudioRenderer> renderer_proxy( | 161 scoped_refptr<MediaStreamAudioRenderer> renderer_proxy( |
| 195 renderer_->CreateSharedAudioRendererProxy(stream_)); | 162 renderer_->CreateSharedAudioRendererProxy(stream_)); |
| 196 renderer_proxy->Start(); | 163 renderer_proxy->Start(); |
| 197 renderer_proxies_.push_back(renderer_proxy); | 164 renderer_proxies_.push_back(renderer_proxy); |
| 198 } | 165 } |
| 199 | 166 |
| 200 // Stop the |renderer_proxy_| should not stop the sink since it is used by | 167 // Stop the |renderer_proxy_| should not stop the sink since it is used by |
| 201 // other proxies. | 168 // other proxies. |
| 202 EXPECT_CALL(*mock_output_device_.get(), Stop()).Times(0); | 169 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(0); |
| 203 renderer_proxy_->Stop(); | 170 renderer_proxy_->Stop(); |
| 204 | 171 |
| 205 for (int i = 0; i < kNumberOfRendererProxy; ++i) { | 172 for (int i = 0; i < kNumberOfRendererProxy; ++i) { |
| 206 if (i != kNumberOfRendererProxy -1) { | 173 if (i != kNumberOfRendererProxy -1) { |
| 207 EXPECT_CALL(*mock_output_device_.get(), Stop()).Times(0); | 174 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(0); |
| 208 } else { | 175 } else { |
| 209 // When the last proxy is stopped, the sink will stop. | 176 // When the last proxy is stopped, the sink will stop. |
| 210 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); | 177 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); |
| 211 EXPECT_CALL(*mock_output_device_.get(), Stop()); | 178 EXPECT_CALL(*mock_sink_.get(), Stop()); |
| 212 } | 179 } |
| 213 renderer_proxies_[i]->Stop(); | 180 renderer_proxies_[i]->Stop(); |
| 214 } | 181 } |
| 215 } | 182 } |
| 216 | 183 |
| 217 // Verify that the sink of the renderer is using the expected sample rate and | 184 // Verify that the sink of the renderer is using the expected sample rate and |
| 218 // buffer size. | 185 // buffer size. |
| 219 TEST_F(WebRtcAudioRendererTest, VerifySinkParameters) { | 186 TEST_F(WebRtcAudioRendererTest, VerifySinkParameters) { |
| 220 SetupRenderer(kDefaultOutputDeviceId); | 187 SetupRenderer(kDefaultOutputDeviceId); |
| 221 renderer_proxy_->Start(); | 188 renderer_proxy_->Start(); |
| 222 #if defined(OS_LINUX) || defined(OS_MACOSX) | 189 #if defined(OS_LINUX) || defined(OS_MACOSX) |
| 223 static const int kExpectedBufferSize = kHardwareSampleRate / 100; | 190 static const int kExpectedBufferSize = kHardwareSampleRate / 100; |
| 224 #elif defined(OS_ANDROID) | 191 #elif defined(OS_ANDROID) |
| 225 static const int kExpectedBufferSize = 2 * kHardwareSampleRate / 100; | 192 static const int kExpectedBufferSize = 2 * kHardwareSampleRate / 100; |
| 226 #else | 193 #else |
| 227 // Windows. | 194 // Windows. |
| 228 static const int kExpectedBufferSize = kHardwareBufferSize; | 195 static const int kExpectedBufferSize = kHardwareBufferSize; |
| 229 #endif | 196 #endif |
| 230 EXPECT_EQ(kExpectedBufferSize, renderer_->frames_per_buffer()); | 197 EXPECT_EQ(kExpectedBufferSize, renderer_->frames_per_buffer()); |
| 231 EXPECT_EQ(kHardwareSampleRate, renderer_->sample_rate()); | 198 EXPECT_EQ(kHardwareSampleRate, renderer_->sample_rate()); |
| 232 EXPECT_EQ(2, renderer_->channels()); | 199 EXPECT_EQ(2, renderer_->channels()); |
| 233 | 200 |
| 234 EXPECT_CALL(*mock_output_device_.get(), Stop()); | 201 EXPECT_CALL(*mock_sink_.get(), Stop()); |
| 235 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); | 202 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); |
| 236 renderer_proxy_->Stop(); | 203 renderer_proxy_->Stop(); |
| 237 } | 204 } |
| 238 | 205 |
| 239 TEST_F(WebRtcAudioRendererTest, NonDefaultDevice) { | 206 TEST_F(WebRtcAudioRendererTest, NonDefaultDevice) { |
| 240 SetupRenderer(kDefaultOutputDeviceId); | 207 SetupRenderer(kDefaultOutputDeviceId); |
| 241 EXPECT_EQ(mock_output_device_->GetDeviceId(), kDefaultOutputDeviceId); | 208 EXPECT_EQ(kDefaultOutputDeviceId, |
| 209 mock_sink_->GetOutputDeviceInfo().device_id()); |
| 242 renderer_proxy_->Start(); | 210 renderer_proxy_->Start(); |
| 243 | 211 |
| 244 EXPECT_CALL(*mock_output_device_.get(), Stop()); | 212 EXPECT_CALL(*mock_sink_.get(), Stop()); |
| 245 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); | 213 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); |
| 246 renderer_proxy_->Stop(); | 214 renderer_proxy_->Stop(); |
| 247 | 215 |
| 248 SetupRenderer(kOtherOutputDeviceId); | 216 SetupRenderer(kOtherOutputDeviceId); |
| 249 EXPECT_EQ(mock_output_device_->GetDeviceId(), kOtherOutputDeviceId); | 217 EXPECT_EQ(kOtherOutputDeviceId, |
| 218 mock_sink_->GetOutputDeviceInfo().device_id()); |
| 250 renderer_proxy_->Start(); | 219 renderer_proxy_->Start(); |
| 251 | 220 |
| 252 EXPECT_CALL(*mock_output_device_.get(), Stop()); | 221 EXPECT_CALL(*mock_sink_.get(), Stop()); |
| 253 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); | 222 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); |
| 254 renderer_proxy_->Stop(); | 223 renderer_proxy_->Stop(); |
| 255 } | 224 } |
| 256 | 225 |
| 257 TEST_F(WebRtcAudioRendererTest, SwitchOutputDevice) { | 226 TEST_F(WebRtcAudioRendererTest, SwitchOutputDevice) { |
| 258 SetupRenderer(kDefaultOutputDeviceId); | 227 SetupRenderer(kDefaultOutputDeviceId); |
| 259 EXPECT_EQ(kDefaultOutputDeviceId, mock_output_device_->GetDeviceId()); | 228 EXPECT_EQ(kDefaultOutputDeviceId, |
| 229 mock_sink_->GetOutputDeviceInfo().device_id()); |
| 260 renderer_proxy_->Start(); | 230 renderer_proxy_->Start(); |
| 261 | 231 |
| 262 EXPECT_CALL(*mock_output_device_.get(), Stop()); | 232 EXPECT_CALL(*mock_sink_.get(), Stop()); |
| 263 EXPECT_CALL(*this, | 233 EXPECT_CALL(*this, |
| 264 MockCreateAudioRendererSink(AudioDeviceFactory::kSourceWebRtc, _, | 234 MockCreateAudioRendererSink(AudioDeviceFactory::kSourceWebRtc, _, |
| 265 _, kOtherOutputDeviceId, _)); | 235 _, kOtherOutputDeviceId, _)); |
| 266 EXPECT_CALL(*source_.get(), AudioRendererThreadStopped()); | 236 EXPECT_CALL(*source_.get(), AudioRendererThreadStopped()); |
| 267 EXPECT_CALL(*this, MockSwitchDeviceCallback(media::OUTPUT_DEVICE_STATUS_OK)); | 237 EXPECT_CALL(*this, MockSwitchDeviceCallback(media::OUTPUT_DEVICE_STATUS_OK)); |
| 268 base::RunLoop loop; | 238 base::RunLoop loop; |
| 269 renderer_proxy_->GetOutputDevice()->SwitchOutputDevice( | 239 renderer_proxy_->SwitchOutputDevice( |
| 270 kOtherOutputDeviceId, url::Origin(), | 240 kOtherOutputDeviceId, url::Origin(), |
| 271 base::Bind(&WebRtcAudioRendererTest::SwitchDeviceCallback, | 241 base::Bind(&WebRtcAudioRendererTest::SwitchDeviceCallback, |
| 272 base::Unretained(this), &loop)); | 242 base::Unretained(this), &loop)); |
| 273 loop.Run(); | 243 loop.Run(); |
| 274 EXPECT_EQ(kOtherOutputDeviceId, mock_output_device_->GetDeviceId()); | 244 EXPECT_EQ(kOtherOutputDeviceId, |
| 245 mock_sink_->GetOutputDeviceInfo().device_id()); |
| 275 | 246 |
| 276 EXPECT_CALL(*mock_output_device_.get(), Stop()); | 247 EXPECT_CALL(*mock_sink_.get(), Stop()); |
| 277 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); | 248 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); |
| 278 renderer_proxy_->Stop(); | 249 renderer_proxy_->Stop(); |
| 279 } | 250 } |
| 280 | 251 |
| 281 TEST_F(WebRtcAudioRendererTest, SwitchOutputDeviceInvalidDevice) { | 252 TEST_F(WebRtcAudioRendererTest, SwitchOutputDeviceInvalidDevice) { |
| 282 SetupRenderer(kDefaultOutputDeviceId); | 253 SetupRenderer(kDefaultOutputDeviceId); |
| 283 EXPECT_EQ(kDefaultOutputDeviceId, mock_output_device_->GetDeviceId()); | 254 EXPECT_EQ(kDefaultOutputDeviceId, |
| 255 mock_sink_->GetOutputDeviceInfo().device_id()); |
| 284 renderer_proxy_->Start(); | 256 renderer_proxy_->Start(); |
| 285 | 257 |
| 286 EXPECT_CALL(*this, | 258 EXPECT_CALL(*this, |
| 287 MockCreateAudioRendererSink(AudioDeviceFactory::kSourceWebRtc, _, | 259 MockCreateAudioRendererSink(AudioDeviceFactory::kSourceWebRtc, _, |
| 288 _, kInvalidOutputDeviceId, _)); | 260 _, kInvalidOutputDeviceId, _)); |
| 289 EXPECT_CALL(*this, MockSwitchDeviceCallback( | 261 EXPECT_CALL(*this, MockSwitchDeviceCallback( |
| 290 media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL)); | 262 media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL)); |
| 291 base::RunLoop loop; | 263 base::RunLoop loop; |
| 292 renderer_proxy_->GetOutputDevice()->SwitchOutputDevice( | 264 renderer_proxy_->SwitchOutputDevice( |
| 293 kInvalidOutputDeviceId, url::Origin(), | 265 kInvalidOutputDeviceId, url::Origin(), |
| 294 base::Bind(&WebRtcAudioRendererTest::SwitchDeviceCallback, | 266 base::Bind(&WebRtcAudioRendererTest::SwitchDeviceCallback, |
| 295 base::Unretained(this), &loop)); | 267 base::Unretained(this), &loop)); |
| 296 loop.Run(); | 268 loop.Run(); |
| 297 EXPECT_EQ(kDefaultOutputDeviceId, mock_output_device_->GetDeviceId()); | 269 EXPECT_EQ(kDefaultOutputDeviceId, |
| 270 mock_sink_->GetOutputDeviceInfo().device_id()); |
| 298 | 271 |
| 299 EXPECT_CALL(*mock_output_device_.get(), Stop()); | 272 EXPECT_CALL(*mock_sink_.get(), Stop()); |
| 300 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); | 273 EXPECT_CALL(*source_.get(), RemoveAudioRenderer(renderer_.get())); |
| 301 renderer_proxy_->Stop(); | 274 renderer_proxy_->Stop(); |
| 302 } | 275 } |
| 303 | 276 |
| 304 } // namespace content | 277 } // namespace content |
| OLD | NEW |