OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/browser/renderer_host/media/audio_renderer_host.h" | 5 #include "content/browser/renderer_host/media/audio_renderer_host.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 }; | 120 }; |
121 | 121 |
122 } // namespace | 122 } // namespace |
123 | 123 |
124 class MockAudioRendererHost : public AudioRendererHost { | 124 class MockAudioRendererHost : public AudioRendererHost { |
125 public: | 125 public: |
126 MockAudioRendererHost(base::RunLoop* auth_run_loop, | 126 MockAudioRendererHost(base::RunLoop* auth_run_loop, |
127 int render_process_id, | 127 int render_process_id, |
128 media::AudioManager* audio_manager, | 128 media::AudioManager* audio_manager, |
129 AudioMirroringManager* mirroring_manager, | 129 AudioMirroringManager* mirroring_manager, |
130 MediaInternals* media_internals, | |
131 MediaStreamManager* media_stream_manager, | 130 MediaStreamManager* media_stream_manager, |
132 const std::string& salt) | 131 const std::string& salt) |
133 : AudioRendererHost(render_process_id, | 132 : AudioRendererHost(render_process_id, |
134 audio_manager, | 133 audio_manager, |
135 mirroring_manager, | 134 mirroring_manager, |
136 media_internals, | |
137 media_stream_manager, | 135 media_stream_manager, |
138 salt), | 136 salt), |
139 shared_memory_length_(0), | 137 shared_memory_length_(0), |
140 auth_run_loop_(auth_run_loop) { | 138 auth_run_loop_(auth_run_loop) { |
141 set_render_frame_id_validate_function_for_testing(&ValidateRenderFrameId); | 139 set_render_frame_id_validate_function_for_testing(&ValidateRenderFrameId); |
142 } | 140 } |
143 | 141 |
144 // A list of mock methods. | 142 // A list of mock methods. |
145 MOCK_METHOD4(OnDeviceAuthorized, | 143 MOCK_METHOD4(OnDeviceAuthorized, |
146 void(int stream_id, | 144 void(int stream_id, |
147 media::OutputDeviceStatus device_status, | 145 media::OutputDeviceStatus device_status, |
148 const media::AudioParameters& output_params, | 146 const media::AudioParameters& output_params, |
149 const std::string& matched_device_id)); | 147 const std::string& matched_device_id)); |
150 MOCK_METHOD2(OnStreamCreated, void(int stream_id, int length)); | 148 MOCK_METHOD2(WasNotifiedOfCreation, void(int stream_id, int length)); |
151 MOCK_METHOD1(OnStreamError, void(int stream_id)); | 149 MOCK_METHOD1(WasNotifiedOfError, void(int stream_id)); |
152 | 150 |
153 void ShutdownForBadMessage() override { bad_msg_count++; } | 151 void ShutdownForBadMessage() override { bad_msg_count++; } |
154 | 152 |
155 int bad_msg_count = 0; | 153 int bad_msg_count = 0; |
156 | 154 |
157 private: | 155 private: |
158 virtual ~MockAudioRendererHost() { | 156 virtual ~MockAudioRendererHost() { |
159 // Make sure all audio streams have been deleted. | 157 // Make sure all audio streams have been deleted. |
160 EXPECT_TRUE(audio_entries_.empty()); | 158 EXPECT_TRUE(delegates_.empty()); |
161 } | 159 } |
162 | 160 |
163 // This method is used to dispatch IPC messages to the renderer. We intercept | 161 // This method is used to dispatch IPC messages to the renderer. We intercept |
164 // these messages here and dispatch to our mock methods to verify the | 162 // these messages here and dispatch to our mock methods to verify the |
165 // conversation between this object and the renderer. | 163 // conversation between this object and the renderer. |
166 // Note: this means that file descriptors won't be duplicated, | 164 // Note: this means that file descriptors won't be duplicated, |
167 // leading to double-close errors from SyncSocket. | 165 // leading to double-close errors from SyncSocket. |
168 // See crbug.com/647659. | 166 // See crbug.com/647659. |
169 bool Send(IPC::Message* message) override { | 167 bool Send(IPC::Message* message) override { |
170 CHECK(message); | 168 CHECK(message); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 CHECK(shared_memory_->Map(length)); | 206 CHECK(shared_memory_->Map(length)); |
209 CHECK(shared_memory_->memory()); | 207 CHECK(shared_memory_->memory()); |
210 shared_memory_length_ = length; | 208 shared_memory_length_ = length; |
211 | 209 |
212 // Create the SyncSocket using the handle. | 210 // Create the SyncSocket using the handle. |
213 base::SyncSocket::Handle sync_socket_handle = | 211 base::SyncSocket::Handle sync_socket_handle = |
214 base::SyncSocket::UnwrapHandle(socket_descriptor); | 212 base::SyncSocket::UnwrapHandle(socket_descriptor); |
215 sync_socket_.reset(new base::SyncSocket(sync_socket_handle)); | 213 sync_socket_.reset(new base::SyncSocket(sync_socket_handle)); |
216 | 214 |
217 // And then delegate the call to the mock method. | 215 // And then delegate the call to the mock method. |
218 OnStreamCreated(stream_id, length); | 216 WasNotifiedOfCreation(stream_id, length); |
219 } | 217 } |
220 | 218 |
221 void OnNotifyStreamError(int stream_id) { OnStreamError(stream_id); } | 219 void OnNotifyStreamError(int stream_id) { WasNotifiedOfError(stream_id); } |
222 | 220 |
223 std::unique_ptr<base::SharedMemory> shared_memory_; | 221 std::unique_ptr<base::SharedMemory> shared_memory_; |
224 std::unique_ptr<base::SyncSocket> sync_socket_; | 222 std::unique_ptr<base::SyncSocket> sync_socket_; |
225 uint32_t shared_memory_length_; | 223 uint32_t shared_memory_length_; |
226 base::RunLoop* auth_run_loop_; // Used to wait for authorization. | 224 base::RunLoop* auth_run_loop_; // Used to wait for authorization. |
227 | 225 |
228 DISALLOW_COPY_AND_ASSIGN(MockAudioRendererHost); | 226 DISALLOW_COPY_AND_ASSIGN(MockAudioRendererHost); |
229 }; | 227 }; |
230 | 228 |
231 class AudioRendererHostTest : public testing::Test { | 229 class AudioRendererHostTest : public testing::Test { |
232 public: | 230 public: |
233 AudioRendererHostTest() | 231 AudioRendererHostTest() |
234 : log_factory(base::MakeUnique<media::FakeAudioLogFactory>()), | 232 : log_factory(base::MakeUnique<media::FakeAudioLogFactory>()), |
235 audio_manager_(base::MakeUnique<FakeAudioManagerWithAssociations>( | 233 audio_manager_(base::MakeUnique<FakeAudioManagerWithAssociations>( |
236 base::ThreadTaskRunnerHandle::Get(), | 234 base::ThreadTaskRunnerHandle::Get(), |
237 log_factory.get())), | 235 log_factory.get())), |
238 render_process_host_(&browser_context_, &auth_run_loop_) { | 236 render_process_host_(&browser_context_, &auth_run_loop_) { |
239 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 237 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
240 switches::kUseFakeDeviceForMediaStream); | 238 switches::kUseFakeDeviceForMediaStream); |
241 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); | 239 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); |
242 host_ = new MockAudioRendererHost( | 240 host_ = new MockAudioRendererHost( |
243 &auth_run_loop_, render_process_host_.GetID(), audio_manager_.get(), | 241 &auth_run_loop_, render_process_host_.GetID(), audio_manager_.get(), |
244 &mirroring_manager_, MediaInternals::GetInstance(), | 242 &mirroring_manager_, media_stream_manager_.get(), kSalt); |
245 media_stream_manager_.get(), kSalt); | |
246 | 243 |
247 // Simulate IPC channel connected. | 244 // Simulate IPC channel connected. |
248 host_->set_peer_process_for_testing(base::Process::Current()); | 245 host_->set_peer_process_for_testing(base::Process::Current()); |
249 } | 246 } |
250 | 247 |
251 ~AudioRendererHostTest() override { | 248 ~AudioRendererHostTest() override { |
252 // Simulate closing the IPC channel and give the audio thread time to close | 249 // Simulate closing the IPC channel and give the audio thread time to close |
253 // the underlying streams. | 250 // the underlying streams. |
254 host_->OnChannelClosing(); | 251 host_->OnChannelClosing(); |
255 SyncWithAudioThread(); | 252 SyncWithAudioThread(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 ? media::OUTPUT_DEVICE_STATUS_OK | 331 ? media::OUTPUT_DEVICE_STATUS_OK |
335 : device_id == kBadDeviceId | 332 : device_id == kBadDeviceId |
336 ? media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED | 333 ? media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED |
337 : media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND; | 334 : media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND; |
338 | 335 |
339 if (expect_onauthorized) | 336 if (expect_onauthorized) |
340 EXPECT_CALL(*host_.get(), | 337 EXPECT_CALL(*host_.get(), |
341 OnDeviceAuthorized(kStreamId, expected_device_status, _, _)); | 338 OnDeviceAuthorized(kStreamId, expected_device_status, _, _)); |
342 | 339 |
343 if (expected_device_status == media::OUTPUT_DEVICE_STATUS_OK) { | 340 if (expected_device_status == media::OUTPUT_DEVICE_STATUS_OK) { |
344 EXPECT_CALL(*host_.get(), OnStreamCreated(kStreamId, _)); | 341 EXPECT_CALL(*host_.get(), WasNotifiedOfCreation(kStreamId, _)); |
345 EXPECT_CALL(mirroring_manager_, AddDiverter(render_process_host_.GetID(), | 342 EXPECT_CALL(mirroring_manager_, AddDiverter(render_process_host_.GetID(), |
346 kRenderFrameId, NotNull())) | 343 kRenderFrameId, NotNull())) |
347 .RetiresOnSaturation(); | 344 .RetiresOnSaturation(); |
348 } | 345 } |
349 | 346 |
350 // Send a create stream message to the audio output stream and wait until | 347 // Send a create stream message to the audio output stream and wait until |
351 // we receive the created message. | 348 // we receive the created message. |
352 media::AudioParameters params( | 349 media::AudioParameters params( |
353 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, | 350 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, |
354 media::AudioParameters::kAudioCDSampleRate, 16, | 351 media::AudioParameters::kAudioCDSampleRate, 16, |
(...skipping 25 matching lines...) Expand all Loading... |
380 SyncWithAudioThread(); | 377 SyncWithAudioThread(); |
381 } | 378 } |
382 | 379 |
383 void CreateWithoutWaitingForAuth(const std::string& device_id) { | 380 void CreateWithoutWaitingForAuth(const std::string& device_id) { |
384 Create(device_id, url::Origin(GURL(kSecurityOrigin)), false, false); | 381 Create(device_id, url::Origin(GURL(kSecurityOrigin)), false, false); |
385 } | 382 } |
386 | 383 |
387 void CreateWithInvalidRenderFrameId() { | 384 void CreateWithInvalidRenderFrameId() { |
388 // When creating a stream with an invalid render frame ID, the host will | 385 // When creating a stream with an invalid render frame ID, the host will |
389 // reply with a stream error message. | 386 // reply with a stream error message. |
390 EXPECT_CALL(*host_, OnStreamError(kStreamId)); | 387 EXPECT_CALL(*host_, WasNotifiedOfError(kStreamId)); |
391 | 388 |
392 // However, validation does not block stream creation, so these method calls | 389 // However, validation does not block stream creation, so these method calls |
393 // might be made: | 390 // might be made: |
394 EXPECT_CALL(*host_, OnStreamCreated(kStreamId, _)).Times(AtLeast(0)); | 391 EXPECT_CALL(*host_, WasNotifiedOfCreation(kStreamId, _)).Times(AtLeast(0)); |
395 EXPECT_CALL(mirroring_manager_, AddDiverter(_, _, _)).Times(AtLeast(0)); | 392 EXPECT_CALL(mirroring_manager_, AddDiverter(_, _, _)).Times(AtLeast(0)); |
396 EXPECT_CALL(mirroring_manager_, RemoveDiverter(_)).Times(AtLeast(0)); | 393 EXPECT_CALL(mirroring_manager_, RemoveDiverter(_)).Times(AtLeast(0)); |
397 | 394 |
398 // Provide a seemingly-valid render frame ID; and it should be rejected when | 395 // Provide a seemingly-valid render frame ID; and it should be rejected when |
399 // AudioRendererHost calls ValidateRenderFrameId(). | 396 // AudioRendererHost calls ValidateRenderFrameId(). |
400 const int kInvalidRenderFrameId = kRenderFrameId + 1; | 397 const int kInvalidRenderFrameId = kRenderFrameId + 1; |
401 const media::AudioParameters params( | 398 const media::AudioParameters params( |
402 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, | 399 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, |
403 media::AudioParameters::kAudioCDSampleRate, 16, | 400 media::AudioParameters::kAudioCDSampleRate, 16, |
404 media::AudioParameters::kAudioCDSampleRate / 10); | 401 media::AudioParameters::kAudioCDSampleRate / 10); |
(...skipping 18 matching lines...) Expand all Loading... |
423 // we receive the created message. | 420 // we receive the created message. |
424 media::AudioParameters params( | 421 media::AudioParameters params( |
425 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, | 422 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, |
426 media::AudioParameters::kAudioCDSampleRate, 16, | 423 media::AudioParameters::kAudioCDSampleRate, 16, |
427 media::AudioParameters::kAudioCDSampleRate / 10); | 424 media::AudioParameters::kAudioCDSampleRate / 10); |
428 | 425 |
429 EXPECT_CALL(*host_.get(), | 426 EXPECT_CALL(*host_.get(), |
430 OnDeviceAuthorized(kStreamId, media::OUTPUT_DEVICE_STATUS_OK, _, | 427 OnDeviceAuthorized(kStreamId, media::OUTPUT_DEVICE_STATUS_OK, _, |
431 hashed_output_id)) | 428 hashed_output_id)) |
432 .Times(1); | 429 .Times(1); |
433 EXPECT_CALL(*host_.get(), OnStreamCreated(kStreamId, _)); | 430 EXPECT_CALL(*host_.get(), WasNotifiedOfCreation(kStreamId, _)); |
434 EXPECT_CALL(mirroring_manager_, AddDiverter(render_process_host_.GetID(), | 431 EXPECT_CALL(mirroring_manager_, AddDiverter(render_process_host_.GetID(), |
435 kRenderFrameId, NotNull())) | 432 kRenderFrameId, NotNull())) |
436 .RetiresOnSaturation(); | 433 .RetiresOnSaturation(); |
437 EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull())) | 434 EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull())) |
438 .RetiresOnSaturation(); | 435 .RetiresOnSaturation(); |
439 | 436 |
440 host_->OnRequestDeviceAuthorization(kStreamId, kRenderFrameId, session_id, | 437 host_->OnRequestDeviceAuthorization(kStreamId, kRenderFrameId, session_id, |
441 /*device id*/ std::string(), | 438 /*device id*/ std::string(), |
442 security_origin); | 439 security_origin); |
443 | 440 |
(...skipping 20 matching lines...) Expand all Loading... |
464 host_->OnPauseStream(kStreamId); | 461 host_->OnPauseStream(kStreamId); |
465 SyncWithAudioThread(); | 462 SyncWithAudioThread(); |
466 } | 463 } |
467 | 464 |
468 void SetVolume(double volume) { | 465 void SetVolume(double volume) { |
469 host_->OnSetVolume(kStreamId, volume); | 466 host_->OnSetVolume(kStreamId, volume); |
470 SyncWithAudioThread(); | 467 SyncWithAudioThread(); |
471 } | 468 } |
472 | 469 |
473 void SimulateError() { | 470 void SimulateError() { |
474 EXPECT_EQ(1u, host_->audio_entries_.size()) | 471 EXPECT_EQ(1u, host_->delegates_.size()) |
475 << "Calls Create() before calling this method"; | 472 << "Calls Create() before calling this method"; |
476 | 473 |
477 // Expect an error signal sent through IPC. | 474 // Expect an error signal sent through IPC. |
478 EXPECT_CALL(*host_.get(), OnStreamError(kStreamId)); | 475 EXPECT_CALL(*host_.get(), WasNotifiedOfError(kStreamId)); |
479 | 476 |
480 // Simulate an error sent from the audio device. | 477 // Simulate an error sent from the audio device. |
481 host_->ReportErrorAndClose(kStreamId); | 478 host_->OnStreamError(kStreamId); |
482 SyncWithAudioThread(); | 479 SyncWithAudioThread(); |
483 | 480 |
484 // Expect the audio stream record is removed. | 481 // Expect the audio stream record is removed. |
485 EXPECT_EQ(0u, host_->audio_entries_.size()); | 482 EXPECT_EQ(0u, host_->delegates_.size()); |
486 } | 483 } |
487 | 484 |
488 // SyncWithAudioThread() waits until all pending tasks on the audio thread | 485 // SyncWithAudioThread() waits until all pending tasks on the audio thread |
489 // are executed while also processing pending task in message_loop_ on the | 486 // are executed while also processing pending task in message_loop_ on the |
490 // current thread. It is used to synchronize with the audio thread when we are | 487 // current thread. It is used to synchronize with the audio thread when we are |
491 // closing an audio stream. | 488 // closing an audio stream. |
492 void SyncWithAudioThread() { | 489 void SyncWithAudioThread() { |
493 base::RunLoop().RunUntilIdle(); | 490 base::RunLoop().RunUntilIdle(); |
494 | 491 |
495 base::RunLoop run_loop; | 492 base::RunLoop run_loop; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 } | 615 } |
619 | 616 |
620 TEST_F(AudioRendererHostTest, CreateFailsForInvalidRenderFrame) { | 617 TEST_F(AudioRendererHostTest, CreateFailsForInvalidRenderFrame) { |
621 CreateWithInvalidRenderFrameId(); | 618 CreateWithInvalidRenderFrameId(); |
622 Close(); | 619 Close(); |
623 } | 620 } |
624 | 621 |
625 // TODO(hclam): Add tests for data conversation in low latency mode. | 622 // TODO(hclam): Add tests for data conversation in low latency mode. |
626 | 623 |
627 } // namespace content | 624 } // namespace content |
OLD | NEW |