| 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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 set_render_frame_id_validate_function_for_testing(&ValidateRenderFrameId); | 94 set_render_frame_id_validate_function_for_testing(&ValidateRenderFrameId); |
| 95 } | 95 } |
| 96 | 96 |
| 97 // A list of mock methods. | 97 // A list of mock methods. |
| 98 MOCK_METHOD0(ShutdownForBadMessage, void()); | 98 MOCK_METHOD0(ShutdownForBadMessage, void()); |
| 99 MOCK_METHOD4(OnDeviceAuthorized, | 99 MOCK_METHOD4(OnDeviceAuthorized, |
| 100 void(int stream_id, | 100 void(int stream_id, |
| 101 media::OutputDeviceStatus device_status, | 101 media::OutputDeviceStatus device_status, |
| 102 const media::AudioParameters& output_params, | 102 const media::AudioParameters& output_params, |
| 103 const std::string& matched_device_id)); | 103 const std::string& matched_device_id)); |
| 104 MOCK_METHOD2(OnStreamCreated, void(int stream_id, int length)); | 104 MOCK_METHOD2(WasNotifiedOfCreation, void(int stream_id, int length)); |
| 105 MOCK_METHOD1(OnStreamError, void(int stream_id)); | 105 MOCK_METHOD1(WasNotifiedOfStreamCreation, void(int stream_id)); |
| 106 | 106 |
| 107 private: | 107 private: |
| 108 virtual ~MockAudioRendererHost() { | 108 virtual ~MockAudioRendererHost() { |
| 109 // Make sure all audio streams have been deleted. | 109 // Make sure all audio streams have been deleted. |
| 110 EXPECT_TRUE(audio_entries_.empty()); | 110 EXPECT_TRUE(delegates_.empty()); |
| 111 } | 111 } |
| 112 | 112 |
| 113 // This method is used to dispatch IPC messages to the renderer. We intercept | 113 // This method is used to dispatch IPC messages to the renderer. We intercept |
| 114 // these messages here and dispatch to our mock methods to verify the | 114 // these messages here and dispatch to our mock methods to verify the |
| 115 // conversation between this object and the renderer. | 115 // conversation between this object and the renderer. |
| 116 // Note: this means that file descriptors won't be duplicated, | 116 // Note: this means that file descriptors won't be duplicated, |
| 117 // leading to double-close errors from SyncSocket. | 117 // leading to double-close errors from SyncSocket. |
| 118 // See crbug.com/647659. | 118 // See crbug.com/647659. |
| 119 virtual bool Send(IPC::Message* message) { | 119 virtual bool Send(IPC::Message* message) { |
| 120 CHECK(message); | 120 CHECK(message); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 CHECK(shared_memory_->Map(length)); | 155 CHECK(shared_memory_->Map(length)); |
| 156 CHECK(shared_memory_->memory()); | 156 CHECK(shared_memory_->memory()); |
| 157 shared_memory_length_ = length; | 157 shared_memory_length_ = length; |
| 158 | 158 |
| 159 // Create the SyncSocket using the handle. | 159 // Create the SyncSocket using the handle. |
| 160 base::SyncSocket::Handle sync_socket_handle = | 160 base::SyncSocket::Handle sync_socket_handle = |
| 161 base::SyncSocket::UnwrapHandle(socket_descriptor); | 161 base::SyncSocket::UnwrapHandle(socket_descriptor); |
| 162 sync_socket_.reset(new base::SyncSocket(sync_socket_handle)); | 162 sync_socket_.reset(new base::SyncSocket(sync_socket_handle)); |
| 163 | 163 |
| 164 // And then delegate the call to the mock method. | 164 // And then delegate the call to the mock method. |
| 165 OnStreamCreated(stream_id, length); | 165 WasNotifiedOfCreation(stream_id, length); |
| 166 } | 166 } |
| 167 | 167 |
| 168 void OnNotifyStreamError(int stream_id) { OnStreamError(stream_id); } | 168 void OnNotifyStreamError(int stream_id) { |
| 169 WasNotifiedOfStreamCreation(stream_id); |
| 170 } |
| 169 | 171 |
| 170 std::unique_ptr<base::SharedMemory> shared_memory_; | 172 std::unique_ptr<base::SharedMemory> shared_memory_; |
| 171 std::unique_ptr<base::SyncSocket> sync_socket_; | 173 std::unique_ptr<base::SyncSocket> sync_socket_; |
| 172 uint32_t shared_memory_length_; | 174 uint32_t shared_memory_length_; |
| 173 base::RunLoop* auth_run_loop_; // Used to wait for authorization. | 175 base::RunLoop* auth_run_loop_; // Used to wait for authorization. |
| 174 | 176 |
| 175 DISALLOW_COPY_AND_ASSIGN(MockAudioRendererHost); | 177 DISALLOW_COPY_AND_ASSIGN(MockAudioRendererHost); |
| 176 }; | 178 }; |
| 177 | 179 |
| 178 class AudioRendererHostTest : public testing::Test { | 180 class AudioRendererHostTest : public testing::Test { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 device_id == kDefaultDeviceId | 220 device_id == kDefaultDeviceId |
| 219 ? media::OUTPUT_DEVICE_STATUS_OK | 221 ? media::OUTPUT_DEVICE_STATUS_OK |
| 220 : device_id == kBadDeviceId | 222 : device_id == kBadDeviceId |
| 221 ? media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED | 223 ? media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED |
| 222 : media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND; | 224 : media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND; |
| 223 | 225 |
| 224 EXPECT_CALL(*host_.get(), | 226 EXPECT_CALL(*host_.get(), |
| 225 OnDeviceAuthorized(kStreamId, expected_device_status, _, _)); | 227 OnDeviceAuthorized(kStreamId, expected_device_status, _, _)); |
| 226 | 228 |
| 227 if (expected_device_status == media::OUTPUT_DEVICE_STATUS_OK) { | 229 if (expected_device_status == media::OUTPUT_DEVICE_STATUS_OK) { |
| 228 EXPECT_CALL(*host_.get(), OnStreamCreated(kStreamId, _)); | 230 EXPECT_CALL(*host_.get(), WasNotifiedOfCreation(kStreamId, _)); |
| 229 EXPECT_CALL(mirroring_manager_, | 231 EXPECT_CALL(mirroring_manager_, |
| 230 AddDiverter(kRenderProcessId, kRenderFrameId, NotNull())) | 232 AddDiverter(kRenderProcessId, kRenderFrameId, NotNull())) |
| 231 .RetiresOnSaturation(); | 233 .RetiresOnSaturation(); |
| 232 } | 234 } |
| 233 | 235 |
| 234 // Send a create stream message to the audio output stream and wait until | 236 // Send a create stream message to the audio output stream and wait until |
| 235 // we receive the created message. | 237 // we receive the created message. |
| 236 media::AudioParameters params( | 238 media::AudioParameters params( |
| 237 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, | 239 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, |
| 238 media::AudioParameters::kAudioCDSampleRate, 16, | 240 media::AudioParameters::kAudioCDSampleRate, 16, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 268 SyncWithAudioThread(); | 270 SyncWithAudioThread(); |
| 269 } | 271 } |
| 270 | 272 |
| 271 void CreateWithoutWaitingForAuth(const std::string& device_id) { | 273 void CreateWithoutWaitingForAuth(const std::string& device_id) { |
| 272 Create(false, device_id, url::Origin(GURL(kSecurityOrigin)), false); | 274 Create(false, device_id, url::Origin(GURL(kSecurityOrigin)), false); |
| 273 } | 275 } |
| 274 | 276 |
| 275 void CreateWithInvalidRenderFrameId() { | 277 void CreateWithInvalidRenderFrameId() { |
| 276 // When creating a stream with an invalid render frame ID, the host will | 278 // When creating a stream with an invalid render frame ID, the host will |
| 277 // reply with a stream error message. | 279 // reply with a stream error message. |
| 278 EXPECT_CALL(*host_, OnStreamError(kStreamId)); | 280 EXPECT_CALL(*host_, WasNotifiedOfStreamCreation(kStreamId)); |
| 279 | 281 |
| 280 // However, validation does not block stream creation, so these method calls | 282 // However, validation does not block stream creation, so these method calls |
| 281 // might be made: | 283 // might be made: |
| 282 EXPECT_CALL(*host_, OnStreamCreated(kStreamId, _)).Times(AtLeast(0)); | 284 EXPECT_CALL(*host_, WasNotifiedOfCreation(kStreamId, _)).Times(AtLeast(0)); |
| 283 EXPECT_CALL(mirroring_manager_, AddDiverter(_, _, _)).Times(AtLeast(0)); | 285 EXPECT_CALL(mirroring_manager_, AddDiverter(_, _, _)).Times(AtLeast(0)); |
| 284 EXPECT_CALL(mirroring_manager_, RemoveDiverter(_)).Times(AtLeast(0)); | 286 EXPECT_CALL(mirroring_manager_, RemoveDiverter(_)).Times(AtLeast(0)); |
| 285 | 287 |
| 286 // Provide a seemingly-valid render frame ID; and it should be rejected when | 288 // Provide a seemingly-valid render frame ID; and it should be rejected when |
| 287 // AudioRendererHost calls ValidateRenderFrameId(). | 289 // AudioRendererHost calls ValidateRenderFrameId(). |
| 288 const int kInvalidRenderFrameId = kRenderFrameId + 1; | 290 const int kInvalidRenderFrameId = kRenderFrameId + 1; |
| 289 const media::AudioParameters params( | 291 const media::AudioParameters params( |
| 290 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, | 292 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, |
| 291 media::AudioParameters::kAudioCDSampleRate, 16, | 293 media::AudioParameters::kAudioCDSampleRate, 16, |
| 292 media::AudioParameters::kAudioCDSampleRate / 10); | 294 media::AudioParameters::kAudioCDSampleRate / 10); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 310 host_->OnPauseStream(kStreamId); | 312 host_->OnPauseStream(kStreamId); |
| 311 SyncWithAudioThread(); | 313 SyncWithAudioThread(); |
| 312 } | 314 } |
| 313 | 315 |
| 314 void SetVolume(double volume) { | 316 void SetVolume(double volume) { |
| 315 host_->OnSetVolume(kStreamId, volume); | 317 host_->OnSetVolume(kStreamId, volume); |
| 316 SyncWithAudioThread(); | 318 SyncWithAudioThread(); |
| 317 } | 319 } |
| 318 | 320 |
| 319 void SimulateError() { | 321 void SimulateError() { |
| 320 EXPECT_EQ(1u, host_->audio_entries_.size()) | 322 EXPECT_EQ(1u, host_->delegates_.size()) |
| 321 << "Calls Create() before calling this method"; | 323 << "Calls Create() before calling this method"; |
| 322 | 324 |
| 323 // Expect an error signal sent through IPC. | 325 // Expect an error signal sent through IPC. |
| 324 EXPECT_CALL(*host_.get(), OnStreamError(kStreamId)); | 326 EXPECT_CALL(*host_.get(), WasNotifiedOfStreamCreation(kStreamId)); |
| 325 | 327 |
| 326 // Simulate an error sent from the audio device. | 328 // Simulate an error sent from the audio device. |
| 327 host_->ReportErrorAndClose(kStreamId); | 329 host_->OnStreamError(kStreamId); |
| 328 SyncWithAudioThread(); | 330 SyncWithAudioThread(); |
| 329 | 331 |
| 330 // Expect the audio stream record is removed. | 332 // Expect the audio stream record is removed. |
| 331 EXPECT_EQ(0u, host_->audio_entries_.size()); | 333 EXPECT_EQ(0u, host_->delegates_.size()); |
| 332 } | 334 } |
| 333 | 335 |
| 334 // SyncWithAudioThread() waits until all pending tasks on the audio thread | 336 // SyncWithAudioThread() waits until all pending tasks on the audio thread |
| 335 // are executed while also processing pending task in message_loop_ on the | 337 // are executed while also processing pending task in message_loop_ on the |
| 336 // current thread. It is used to synchronize with the audio thread when we are | 338 // current thread. It is used to synchronize with the audio thread when we are |
| 337 // closing an audio stream. | 339 // closing an audio stream. |
| 338 void SyncWithAudioThread() { | 340 void SyncWithAudioThread() { |
| 339 base::RunLoop().RunUntilIdle(); | 341 base::RunLoop().RunUntilIdle(); |
| 340 | 342 |
| 341 base::RunLoop run_loop; | 343 base::RunLoop run_loop; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 } | 451 } |
| 450 | 452 |
| 451 TEST_F(AudioRendererHostTest, CreateFailsForInvalidRenderFrame) { | 453 TEST_F(AudioRendererHostTest, CreateFailsForInvalidRenderFrame) { |
| 452 CreateWithInvalidRenderFrameId(); | 454 CreateWithInvalidRenderFrameId(); |
| 453 Close(); | 455 Close(); |
| 454 } | 456 } |
| 455 | 457 |
| 456 // TODO(hclam): Add tests for data conversation in low latency mode. | 458 // TODO(hclam): Add tests for data conversation in low latency mode. |
| 457 | 459 |
| 458 } // namespace content | 460 } // namespace content |
| OLD | NEW |