| 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 11 matching lines...) Expand all Loading... |
| 22 #include "content/public/test/test_browser_thread_bundle.h" | 22 #include "content/public/test/test_browser_thread_bundle.h" |
| 23 #include "ipc/ipc_message_utils.h" | 23 #include "ipc/ipc_message_utils.h" |
| 24 #include "media/audio/audio_manager.h" | 24 #include "media/audio/audio_manager.h" |
| 25 #include "media/base/bind_to_current_loop.h" | 25 #include "media/base/bind_to_current_loop.h" |
| 26 #include "media/base/media_switches.h" | 26 #include "media/base/media_switches.h" |
| 27 #include "testing/gmock/include/gmock/gmock.h" | 27 #include "testing/gmock/include/gmock/gmock.h" |
| 28 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
| 29 | 29 |
| 30 using ::testing::_; | 30 using ::testing::_; |
| 31 using ::testing::Assign; | 31 using ::testing::Assign; |
| 32 using ::testing::AtLeast; |
| 32 using ::testing::DoAll; | 33 using ::testing::DoAll; |
| 33 using ::testing::NotNull; | 34 using ::testing::NotNull; |
| 34 | 35 |
| 35 namespace content { | 36 namespace content { |
| 36 | 37 |
| 37 namespace { | 38 namespace { |
| 38 const int kRenderProcessId = 1; | 39 const int kRenderProcessId = 1; |
| 39 const int kRenderFrameId = 5; | 40 const int kRenderFrameId = 5; |
| 40 const int kStreamId = 50; | 41 const int kStreamId = 50; |
| 41 const char kSecurityOrigin[] = "http://localhost"; | 42 const char kSecurityOrigin[] = "http://localhost"; |
| 42 const char kDefaultDeviceId[] = ""; | 43 const char kDefaultDeviceId[] = ""; |
| 43 const char kBadDeviceId[] = | 44 const char kBadDeviceId[] = |
| 44 "badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad1"; | 45 "badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad1"; |
| 45 const char kInvalidDeviceId[] = "invalid-device-id"; | 46 const char kInvalidDeviceId[] = "invalid-device-id"; |
| 46 | 47 |
| 47 #if DCHECK_IS_ON() | |
| 48 void ValidateRenderFrameId(int render_process_id, | 48 void ValidateRenderFrameId(int render_process_id, |
| 49 int render_frame_id, | 49 int render_frame_id, |
| 50 const base::Callback<void(bool)>& callback) { | 50 const base::Callback<void(bool)>& callback) { |
| 51 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 51 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 52 const bool frame_exists = (render_process_id == kRenderProcessId && | 52 const bool frame_exists = (render_process_id == kRenderProcessId && |
| 53 render_frame_id == kRenderFrameId); | 53 render_frame_id == kRenderFrameId); |
| 54 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 54 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 55 base::Bind(callback, frame_exists)); | 55 base::Bind(callback, frame_exists)); |
| 56 } | 56 } |
| 57 #endif // DCHECK_IS_ON() | |
| 58 | 57 |
| 59 } // namespace | 58 } // namespace |
| 60 | 59 |
| 61 class MockAudioMirroringManager : public AudioMirroringManager { | 60 class MockAudioMirroringManager : public AudioMirroringManager { |
| 62 public: | 61 public: |
| 63 MockAudioMirroringManager() {} | 62 MockAudioMirroringManager() {} |
| 64 virtual ~MockAudioMirroringManager() {} | 63 virtual ~MockAudioMirroringManager() {} |
| 65 | 64 |
| 66 MOCK_METHOD3(AddDiverter, | 65 MOCK_METHOD3(AddDiverter, |
| 67 void(int render_process_id, | 66 void(int render_process_id, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 80 MediaInternals* media_internals, | 79 MediaInternals* media_internals, |
| 81 MediaStreamManager* media_stream_manager, | 80 MediaStreamManager* media_stream_manager, |
| 82 const std::string& salt) | 81 const std::string& salt) |
| 83 : AudioRendererHost(kRenderProcessId, | 82 : AudioRendererHost(kRenderProcessId, |
| 84 audio_manager, | 83 audio_manager, |
| 85 mirroring_manager, | 84 mirroring_manager, |
| 86 media_internals, | 85 media_internals, |
| 87 media_stream_manager, | 86 media_stream_manager, |
| 88 salt), | 87 salt), |
| 89 shared_memory_length_(0) { | 88 shared_memory_length_(0) { |
| 90 #if DCHECK_IS_ON() | |
| 91 set_render_frame_id_validate_function_for_testing(&ValidateRenderFrameId); | 89 set_render_frame_id_validate_function_for_testing(&ValidateRenderFrameId); |
| 92 #endif // DCHECK_IS_ON() | |
| 93 } | 90 } |
| 94 | 91 |
| 95 // A list of mock methods. | 92 // A list of mock methods. |
| 96 MOCK_METHOD4(OnDeviceAuthorized, | 93 MOCK_METHOD4(OnDeviceAuthorized, |
| 97 void(int stream_id, | 94 void(int stream_id, |
| 98 media::OutputDeviceStatus device_status, | 95 media::OutputDeviceStatus device_status, |
| 99 const media::AudioParameters& output_params, | 96 const media::AudioParameters& output_params, |
| 100 const std::string& matched_device_id)); | 97 const std::string& matched_device_id)); |
| 101 MOCK_METHOD2(OnStreamCreated, void(int stream_id, int length)); | 98 MOCK_METHOD2(OnStreamCreated, void(int stream_id, int length)); |
| 102 MOCK_METHOD1(OnStreamPlaying, void(int stream_id)); | 99 MOCK_METHOD1(OnStreamPlaying, void(int stream_id)); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 | 274 |
| 278 // At some point in the future, a corresponding RemoveDiverter() call must | 275 // At some point in the future, a corresponding RemoveDiverter() call must |
| 279 // be made. | 276 // be made. |
| 280 EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull())) | 277 EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull())) |
| 281 .RetiresOnSaturation(); | 278 .RetiresOnSaturation(); |
| 282 } | 279 } |
| 283 SyncWithAudioThread(); | 280 SyncWithAudioThread(); |
| 284 } | 281 } |
| 285 | 282 |
| 286 void CreateWithInvalidRenderFrameId() { | 283 void CreateWithInvalidRenderFrameId() { |
| 287 // Because the render frame is invalid, the host should only reply with a | 284 // When creating a stream with an invalid render frame ID, the host will |
| 288 // stream error message. | 285 // reply with a stream error message. |
| 289 EXPECT_CALL(*host_, OnStreamError(kStreamId)); | 286 EXPECT_CALL(*host_, OnStreamError(kStreamId)); |
| 290 | 287 |
| 291 // When DCHECKs are on, provide a seemingly-valid render frame ID; and it | 288 // However, validation does not block stream creation, so these method calls |
| 292 // should be rejected when AudioRendererHost calls | 289 // might be made: |
| 293 // ValidateRenderFrameId(). When DCHECKs are off, AudioRendererHost won't | 290 EXPECT_CALL(*host_, OnStreamCreated(kStreamId, _)).Times(AtLeast(0)); |
| 294 // call the validation function, but can still reject a render frame ID when | 291 EXPECT_CALL(mirroring_manager_, AddDiverter(_, _, _)).Times(AtLeast(0)); |
| 295 // it is obviously bogus. | 292 EXPECT_CALL(mirroring_manager_, RemoveDiverter(_)).Times(AtLeast(0)); |
| 296 #if DCHECK_IS_ON() | 293 |
| 294 // Provide a seemingly-valid render frame ID; and it should be rejected when |
| 295 // AudioRendererHost calls ValidateRenderFrameId(). |
| 297 const int kInvalidRenderFrameId = kRenderFrameId + 1; | 296 const int kInvalidRenderFrameId = kRenderFrameId + 1; |
| 298 #else | |
| 299 const int kInvalidRenderFrameId = MSG_ROUTING_NONE; | |
| 300 #endif // DCHECK_IS_ON() | |
| 301 | |
| 302 const media::AudioParameters params( | 297 const media::AudioParameters params( |
| 303 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, | 298 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO, |
| 304 media::AudioParameters::kAudioCDSampleRate, 16, | 299 media::AudioParameters::kAudioCDSampleRate, 16, |
| 305 media::AudioParameters::kAudioCDSampleRate / 10); | 300 media::AudioParameters::kAudioCDSampleRate / 10); |
| 306 host_->OnCreateStream(kStreamId, kInvalidRenderFrameId, params); | 301 host_->OnCreateStream(kStreamId, kInvalidRenderFrameId, params); |
| 302 base::RunLoop().RunUntilIdle(); |
| 307 } | 303 } |
| 308 | 304 |
| 309 void Close() { | 305 void Close() { |
| 310 // Send a message to AudioRendererHost to tell it we want to close the | 306 // Send a message to AudioRendererHost to tell it we want to close the |
| 311 // stream. | 307 // stream. |
| 312 host_->OnCloseStream(kStreamId); | 308 host_->OnCloseStream(kStreamId); |
| 313 SyncWithAudioThread(); | 309 SyncWithAudioThread(); |
| 314 } | 310 } |
| 315 | 311 |
| 316 void Play() { | 312 void Play() { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 } | 442 } |
| 447 | 443 |
| 448 TEST_F(AudioRendererHostTest, CreateFailsForInvalidRenderFrame) { | 444 TEST_F(AudioRendererHostTest, CreateFailsForInvalidRenderFrame) { |
| 449 CreateWithInvalidRenderFrameId(); | 445 CreateWithInvalidRenderFrameId(); |
| 450 Close(); | 446 Close(); |
| 451 } | 447 } |
| 452 | 448 |
| 453 // TODO(hclam): Add tests for data conversation in low latency mode. | 449 // TODO(hclam): Add tests for data conversation in low latency mode. |
| 454 | 450 |
| 455 } // namespace content | 451 } // namespace content |
| OLD | NEW |