| 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 | 
|---|