| 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 <stdint.h> | 5 #include <stdint.h> |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 using testing::Values; | 40 using testing::Values; |
| 41 | 41 |
| 42 namespace media { | 42 namespace media { |
| 43 | 43 |
| 44 namespace { | 44 namespace { |
| 45 | 45 |
| 46 const char kDefaultDeviceId[] = ""; | 46 const char kDefaultDeviceId[] = ""; |
| 47 const char kNonDefaultDeviceId[] = "valid-nondefault-device-id"; | 47 const char kNonDefaultDeviceId[] = "valid-nondefault-device-id"; |
| 48 const char kUnauthorizedDeviceId[] = "unauthorized-device-id"; | 48 const char kUnauthorizedDeviceId[] = "unauthorized-device-id"; |
| 49 const int kAuthTimeoutForTestingMs = 500; | 49 const int kAuthTimeoutForTestingMs = 500; |
| 50 const int kOutputDelayMs = 20; |
| 50 | 51 |
| 51 class MockRenderCallback : public AudioRendererSink::RenderCallback { | 52 class MockRenderCallback : public AudioRendererSink::RenderCallback { |
| 52 public: | 53 public: |
| 53 MockRenderCallback() {} | 54 MockRenderCallback() {} |
| 54 virtual ~MockRenderCallback() {} | 55 virtual ~MockRenderCallback() {} |
| 55 | 56 |
| 56 MOCK_METHOD3(Render, | 57 MOCK_METHOD4(Render, |
| 57 int(AudioBus* dest, | 58 int(base::TimeDelta delay, |
| 58 uint32_t frames_delayed, | 59 base::TimeTicks timestamp, |
| 59 uint32_t frames_skipped)); | 60 int prior_frames_skipped, |
| 61 AudioBus* dest)); |
| 60 MOCK_METHOD0(OnRenderError, void()); | 62 MOCK_METHOD0(OnRenderError, void()); |
| 61 }; | 63 }; |
| 62 | 64 |
| 63 class MockAudioOutputIPC : public AudioOutputIPC { | 65 class MockAudioOutputIPC : public AudioOutputIPC { |
| 64 public: | 66 public: |
| 65 MockAudioOutputIPC() {} | 67 MockAudioOutputIPC() {} |
| 66 virtual ~MockAudioOutputIPC() {} | 68 virtual ~MockAudioOutputIPC() {} |
| 67 | 69 |
| 68 MOCK_METHOD4(RequestDeviceAuthorization, | 70 MOCK_METHOD4(RequestDeviceAuthorization, |
| 69 void(AudioOutputIPCDelegate* delegate, | 71 void(AudioOutputIPCDelegate* delegate, |
| 70 int session_id, | 72 int session_id, |
| 71 const std::string& device_id, | 73 const std::string& device_id, |
| 72 const url::Origin& security_origin)); | 74 const url::Origin& security_origin)); |
| 73 MOCK_METHOD2(CreateStream, | 75 MOCK_METHOD2(CreateStream, |
| 74 void(AudioOutputIPCDelegate* delegate, | 76 void(AudioOutputIPCDelegate* delegate, |
| 75 const AudioParameters& params)); | 77 const AudioParameters& params)); |
| 76 MOCK_METHOD0(PlayStream, void()); | 78 MOCK_METHOD0(PlayStream, void()); |
| 77 MOCK_METHOD0(PauseStream, void()); | 79 MOCK_METHOD0(PauseStream, void()); |
| 78 MOCK_METHOD0(CloseStream, void()); | 80 MOCK_METHOD0(CloseStream, void()); |
| 79 MOCK_METHOD1(SetVolume, void(double volume)); | 81 MOCK_METHOD1(SetVolume, void(double volume)); |
| 80 }; | 82 }; |
| 81 | 83 |
| 82 ACTION_P2(SendPendingBytes, socket, pending_bytes) { | 84 ACTION_P2(RequestMoreData, socket, shared_memory) { |
| 83 socket->Send(&pending_bytes, sizeof(pending_bytes)); | 85 AudioOutputBuffer* buffer = |
| 86 reinterpret_cast<AudioOutputBuffer*>(shared_memory->memory()); |
| 87 buffer->params.frames_skipped = 0; |
| 88 buffer->params.delay = |
| 89 base::TimeDelta::FromMilliseconds(kOutputDelayMs).InMicroseconds(); |
| 90 buffer->params.delay_timestamp = |
| 91 (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds(); |
| 92 |
| 93 constexpr int kControlSignal = 0; |
| 94 socket->Send(&kControlSignal, sizeof(kControlSignal)); |
| 84 } | 95 } |
| 85 | 96 |
| 86 // Used to terminate a loop from a different thread than the loop belongs to. | 97 // Used to terminate a loop from a different thread than the loop belongs to. |
| 87 // |task_runner| should be a SingleThreadTaskRunner. | 98 // |task_runner| should be a SingleThreadTaskRunner. |
| 88 ACTION_P(QuitLoop, task_runner) { | 99 ACTION_P(QuitLoop, task_runner) { |
| 89 task_runner->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); | 100 task_runner->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); |
| 90 } | 101 } |
| 91 | 102 |
| 92 } // namespace. | 103 } // namespace. |
| 93 | 104 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 duplicated_memory_handle, | 231 duplicated_memory_handle, |
| 221 SyncSocket::UnwrapHandle(audio_device_socket_descriptor), kMemorySize); | 232 SyncSocket::UnwrapHandle(audio_device_socket_descriptor), kMemorySize); |
| 222 base::RunLoop().RunUntilIdle(); | 233 base::RunLoop().RunUntilIdle(); |
| 223 } | 234 } |
| 224 | 235 |
| 225 void AudioOutputDeviceTest::ExpectRenderCallback() { | 236 void AudioOutputDeviceTest::ExpectRenderCallback() { |
| 226 // We should get a 'play' notification when we call OnStreamCreated(). | 237 // We should get a 'play' notification when we call OnStreamCreated(). |
| 227 // Respond by asking for some audio data. This should ask our callback | 238 // Respond by asking for some audio data. This should ask our callback |
| 228 // to provide some audio data that AudioOutputDevice then writes into the | 239 // to provide some audio data that AudioOutputDevice then writes into the |
| 229 // shared memory section. | 240 // shared memory section. |
| 230 const int kMemorySize = CalculateMemorySize(); | |
| 231 | |
| 232 EXPECT_CALL(*audio_output_ipc_, PlayStream()) | 241 EXPECT_CALL(*audio_output_ipc_, PlayStream()) |
| 233 .WillOnce(SendPendingBytes(&browser_socket_, kMemorySize)); | 242 .WillOnce(RequestMoreData(&browser_socket_, &shared_memory_)); |
| 234 | 243 |
| 235 // We expect calls to our audio renderer callback, which returns the number | 244 // We expect calls to our audio renderer callback, which returns the number |
| 236 // of frames written to the memory section. | 245 // of frames written to the memory section. |
| 237 // Here's the second place where it gets hacky: There's no way for us to | 246 // Here's the second place where it gets hacky: There's no way for us to |
| 238 // know (without using a sleep loop!) when the AudioOutputDevice has finished | 247 // know (without using a sleep loop!) when the AudioOutputDevice has finished |
| 239 // writing the interleaved audio data into the shared memory section. | 248 // writing the interleaved audio data into the shared memory section. |
| 240 // So, for the sake of this test, we consider the call to Render a sign | 249 // So, for the sake of this test, we consider the call to Render a sign |
| 241 // of success and quit the loop. | 250 // of success and quit the loop. |
| 242 const int kNumberOfFramesToProcess = 0; | 251 const int kNumberOfFramesToProcess = 0; |
| 243 EXPECT_CALL(callback_, Render(_, _, _)) | 252 EXPECT_CALL( |
| 253 callback_, |
| 254 Render(base::TimeDelta::FromMilliseconds(kOutputDelayMs), _, _, _)) |
| 244 .WillOnce(DoAll(QuitLoop(io_loop_.task_runner()), | 255 .WillOnce(DoAll(QuitLoop(io_loop_.task_runner()), |
| 245 Return(kNumberOfFramesToProcess))); | 256 Return(kNumberOfFramesToProcess))); |
| 246 } | 257 } |
| 247 | 258 |
| 248 void AudioOutputDeviceTest::WaitUntilRenderCallback() { | 259 void AudioOutputDeviceTest::WaitUntilRenderCallback() { |
| 249 // Don't hang the test if we never get the Render() callback. | 260 // Don't hang the test if we never get the Render() callback. |
| 250 io_loop_.task_runner()->PostDelayedTask( | 261 io_loop_.task_runner()->PostDelayedTask( |
| 251 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), | 262 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), |
| 252 TestTimeouts::action_timeout()); | 263 TestTimeouts::action_timeout()); |
| 253 base::RunLoop().Run(); | 264 base::RunLoop().Run(); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 // Runs the loop and waits for |thread| to call event's closure. | 374 // Runs the loop and waits for |thread| to call event's closure. |
| 364 event.RunAndWait(); | 375 event.RunAndWait(); |
| 365 | 376 |
| 366 audio_device_->Stop(); | 377 audio_device_->Stop(); |
| 367 base::RunLoop().RunUntilIdle(); | 378 base::RunLoop().RunUntilIdle(); |
| 368 } | 379 } |
| 369 | 380 |
| 370 INSTANTIATE_TEST_CASE_P(Render, AudioOutputDeviceTest, Values(false)); | 381 INSTANTIATE_TEST_CASE_P(Render, AudioOutputDeviceTest, Values(false)); |
| 371 | 382 |
| 372 } // namespace media. | 383 } // namespace media. |
| OLD | NEW |