| 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 <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "base/at_exit.h" | 7 #include "base/at_exit.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/memory/shared_memory.h" | 10 #include "base/memory/shared_memory.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 using testing::Invoke; | 28 using testing::Invoke; |
| 29 using testing::Return; | 29 using testing::Return; |
| 30 using testing::WithArgs; | 30 using testing::WithArgs; |
| 31 using testing::StrictMock; | 31 using testing::StrictMock; |
| 32 using testing::Values; | 32 using testing::Values; |
| 33 | 33 |
| 34 namespace media { | 34 namespace media { |
| 35 | 35 |
| 36 namespace { | 36 namespace { |
| 37 | 37 |
| 38 const std::string kNonDefaultDeviceId("fake-device-id"); |
| 39 |
| 38 class MockRenderCallback : public AudioRendererSink::RenderCallback { | 40 class MockRenderCallback : public AudioRendererSink::RenderCallback { |
| 39 public: | 41 public: |
| 40 MockRenderCallback() {} | 42 MockRenderCallback() {} |
| 41 virtual ~MockRenderCallback() {} | 43 virtual ~MockRenderCallback() {} |
| 42 | 44 |
| 43 MOCK_METHOD2(Render, int(AudioBus* dest, int audio_delay_milliseconds)); | 45 MOCK_METHOD2(Render, int(AudioBus* dest, int audio_delay_milliseconds)); |
| 44 MOCK_METHOD0(OnRenderError, void()); | 46 MOCK_METHOD0(OnRenderError, void()); |
| 45 }; | 47 }; |
| 46 | 48 |
| 47 class MockAudioOutputIPC : public AudioOutputIPC { | 49 class MockAudioOutputIPC : public AudioOutputIPC { |
| 48 public: | 50 public: |
| 49 MockAudioOutputIPC() {} | 51 MockAudioOutputIPC() {} |
| 50 virtual ~MockAudioOutputIPC() {} | 52 virtual ~MockAudioOutputIPC() {} |
| 51 | 53 |
| 52 MOCK_METHOD3(CreateStream, void(AudioOutputIPCDelegate* delegate, | 54 MOCK_METHOD4(RequestDeviceAuthorization, |
| 53 const AudioParameters& params, | 55 void(AudioOutputIPCDelegate* delegate, |
| 54 int session_id)); | 56 int session_id, |
| 57 const std::string& device_id, |
| 58 const url::Origin& security_origin)); |
| 59 MOCK_METHOD2(CreateStream, |
| 60 void(AudioOutputIPCDelegate* delegate, |
| 61 const AudioParameters& params)); |
| 55 MOCK_METHOD0(PlayStream, void()); | 62 MOCK_METHOD0(PlayStream, void()); |
| 56 MOCK_METHOD0(PauseStream, void()); | 63 MOCK_METHOD0(PauseStream, void()); |
| 57 MOCK_METHOD0(CloseStream, void()); | 64 MOCK_METHOD0(CloseStream, void()); |
| 58 MOCK_METHOD1(SetVolume, void(double volume)); | 65 MOCK_METHOD1(SetVolume, void(double volume)); |
| 59 MOCK_METHOD3(SwitchOutputDevice, | 66 MOCK_METHOD2(SwitchOutputDevice, |
| 60 void(const std::string& device_id, | 67 void(const std::string& device_id, |
| 61 const GURL& security_origin, | 68 const url::Origin& security_origin)); |
| 62 int request_id)); | |
| 63 }; | 69 }; |
| 64 | 70 |
| 65 class MockSwitchOutputDeviceCallback { | 71 class MockSwitchOutputDeviceCallback { |
| 66 public: | 72 public: |
| 67 MOCK_METHOD1(Callback, void(media::SwitchOutputDeviceResult result)); | 73 MOCK_METHOD1(Callback, void(media::SwitchOutputDeviceResult result)); |
| 68 }; | 74 }; |
| 69 | 75 |
| 70 ACTION_P2(SendPendingBytes, socket, pending_bytes) { | 76 ACTION_P2(SendPendingBytes, socket, pending_bytes) { |
| 71 socket->Send(&pending_bytes, sizeof(pending_bytes)); | 77 socket->Send(&pending_bytes, sizeof(pending_bytes)); |
| 72 } | 78 } |
| 73 | 79 |
| 74 // Used to terminate a loop from a different thread than the loop belongs to. | 80 // Used to terminate a loop from a different thread than the loop belongs to. |
| 75 // |task_runner| should be a SingleThreadTaskRunner. | 81 // |task_runner| should be a SingleThreadTaskRunner. |
| 76 ACTION_P(QuitLoop, task_runner) { | 82 ACTION_P(QuitLoop, task_runner) { |
| 77 task_runner->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); | 83 task_runner->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); |
| 78 } | 84 } |
| 79 | 85 |
| 80 } // namespace. | 86 } // namespace. |
| 81 | 87 |
| 82 class AudioOutputDeviceTest | 88 class AudioOutputDeviceTest |
| 83 : public testing::Test, | 89 : public testing::Test, |
| 84 public testing::WithParamInterface<bool> { | 90 public testing::WithParamInterface<bool> { |
| 85 public: | 91 public: |
| 86 AudioOutputDeviceTest(); | 92 AudioOutputDeviceTest(); |
| 87 ~AudioOutputDeviceTest(); | 93 ~AudioOutputDeviceTest(); |
| 88 | 94 |
| 95 void ReceiveAuthorization(); |
| 89 void StartAudioDevice(); | 96 void StartAudioDevice(); |
| 90 void CreateStream(); | 97 void CreateStream(); |
| 91 void ExpectRenderCallback(); | 98 void ExpectRenderCallback(); |
| 92 void WaitUntilRenderCallback(); | 99 void WaitUntilRenderCallback(); |
| 93 void StopAudioDevice(); | 100 void StopAudioDevice(); |
| 94 void SwitchOutputDevice(); | 101 void SwitchOutputDevice(); |
| 102 void SetDevice(const std::string& device_id); |
| 95 | 103 |
| 96 protected: | 104 protected: |
| 97 // Used to clean up TLS pointers that the test(s) will initialize. | 105 // Used to clean up TLS pointers that the test(s) will initialize. |
| 98 // Must remain the first member of this class. | 106 // Must remain the first member of this class. |
| 99 base::ShadowingAtExitManager at_exit_manager_; | 107 base::ShadowingAtExitManager at_exit_manager_; |
| 100 base::MessageLoopForIO io_loop_; | 108 base::MessageLoopForIO io_loop_; |
| 101 AudioParameters default_audio_parameters_; | 109 AudioParameters default_audio_parameters_; |
| 102 StrictMock<MockRenderCallback> callback_; | 110 StrictMock<MockRenderCallback> callback_; |
| 103 MockAudioOutputIPC* audio_output_ipc_; // owned by audio_device_ | 111 MockAudioOutputIPC* audio_output_ipc_; // owned by audio_device_ |
| 104 scoped_refptr<AudioOutputDevice> audio_device_; | 112 scoped_refptr<AudioOutputDevice> audio_device_; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 116 }; | 124 }; |
| 117 | 125 |
| 118 int AudioOutputDeviceTest::CalculateMemorySize() { | 126 int AudioOutputDeviceTest::CalculateMemorySize() { |
| 119 // Calculate output memory size. | 127 // Calculate output memory size. |
| 120 return AudioBus::CalculateMemorySize(default_audio_parameters_); | 128 return AudioBus::CalculateMemorySize(default_audio_parameters_); |
| 121 } | 129 } |
| 122 | 130 |
| 123 AudioOutputDeviceTest::AudioOutputDeviceTest() { | 131 AudioOutputDeviceTest::AudioOutputDeviceTest() { |
| 124 default_audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LINEAR, | 132 default_audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LINEAR, |
| 125 CHANNEL_LAYOUT_STEREO, 48000, 16, 1024); | 133 CHANNEL_LAYOUT_STEREO, 48000, 16, 1024); |
| 126 | 134 SetDevice(std::string()); // Use default device |
| 127 audio_output_ipc_ = new MockAudioOutputIPC(); | |
| 128 audio_device_ = new AudioOutputDevice( | |
| 129 scoped_ptr<AudioOutputIPC>(audio_output_ipc_), | |
| 130 io_loop_.task_runner()); | |
| 131 | |
| 132 audio_device_->Initialize(default_audio_parameters_, | |
| 133 &callback_); | |
| 134 | |
| 135 io_loop_.RunUntilIdle(); | |
| 136 } | 135 } |
| 137 | 136 |
| 138 AudioOutputDeviceTest::~AudioOutputDeviceTest() { | 137 AudioOutputDeviceTest::~AudioOutputDeviceTest() { |
| 139 audio_device_ = NULL; | 138 audio_device_ = NULL; |
| 140 } | 139 } |
| 141 | 140 |
| 141 void AudioOutputDeviceTest::SetDevice(const std::string& device_id) { |
| 142 audio_output_ipc_ = new MockAudioOutputIPC(); |
| 143 audio_device_ = new AudioOutputDevice( |
| 144 scoped_ptr<AudioOutputIPC>(audio_output_ipc_), io_loop_.task_runner(), 0, |
| 145 device_id, url::Origin()); |
| 146 audio_device_->RequestDeviceAuthorization(); |
| 147 EXPECT_CALL(*audio_output_ipc_, |
| 148 RequestDeviceAuthorization(audio_device_.get(), 0, device_id, _)); |
| 149 io_loop_.RunUntilIdle(); |
| 150 |
| 151 // Simulate response from browser |
| 152 ReceiveAuthorization(); |
| 153 |
| 154 audio_device_->Initialize(default_audio_parameters_, |
| 155 &callback_); |
| 156 } |
| 157 |
| 158 void AudioOutputDeviceTest::ReceiveAuthorization() { |
| 159 audio_device_->OnDeviceAuthorized(true, default_audio_parameters_); |
| 160 io_loop_.RunUntilIdle(); |
| 161 } |
| 162 |
| 142 void AudioOutputDeviceTest::StartAudioDevice() { | 163 void AudioOutputDeviceTest::StartAudioDevice() { |
| 143 audio_device_->Start(); | 164 audio_device_->Start(); |
| 144 | 165 EXPECT_CALL(*audio_output_ipc_, CreateStream(audio_device_.get(), _)); |
| 145 EXPECT_CALL(*audio_output_ipc_, CreateStream(audio_device_.get(), _, 0)); | |
| 146 | 166 |
| 147 io_loop_.RunUntilIdle(); | 167 io_loop_.RunUntilIdle(); |
| 148 } | 168 } |
| 149 | 169 |
| 150 void AudioOutputDeviceTest::CreateStream() { | 170 void AudioOutputDeviceTest::CreateStream() { |
| 151 const int kMemorySize = CalculateMemorySize(); | 171 const int kMemorySize = CalculateMemorySize(); |
| 152 | 172 |
| 153 ASSERT_TRUE(shared_memory_.CreateAndMapAnonymous(kMemorySize)); | 173 ASSERT_TRUE(shared_memory_.CreateAndMapAnonymous(kMemorySize)); |
| 154 memset(shared_memory_.memory(), 0xff, kMemorySize); | 174 memset(shared_memory_.memory(), 0xff, kMemorySize); |
| 155 | 175 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 | 225 |
| 206 void AudioOutputDeviceTest::StopAudioDevice() { | 226 void AudioOutputDeviceTest::StopAudioDevice() { |
| 207 audio_device_->Stop(); | 227 audio_device_->Stop(); |
| 208 | 228 |
| 209 EXPECT_CALL(*audio_output_ipc_, CloseStream()); | 229 EXPECT_CALL(*audio_output_ipc_, CloseStream()); |
| 210 | 230 |
| 211 io_loop_.RunUntilIdle(); | 231 io_loop_.RunUntilIdle(); |
| 212 } | 232 } |
| 213 | 233 |
| 214 void AudioOutputDeviceTest::SwitchOutputDevice() { | 234 void AudioOutputDeviceTest::SwitchOutputDevice() { |
| 215 const GURL security_origin("http://localhost"); | |
| 216 const std::string device_id; | |
| 217 const int request_id = 1; | |
| 218 | |
| 219 // Switch the output device and check that the IPC message is sent | 235 // Switch the output device and check that the IPC message is sent |
| 220 EXPECT_CALL(*audio_output_ipc_, | 236 EXPECT_CALL(*audio_output_ipc_, SwitchOutputDevice(kNonDefaultDeviceId, _)); |
| 221 SwitchOutputDevice(device_id, security_origin, request_id)); | |
| 222 audio_device_->SwitchOutputDevice( | 237 audio_device_->SwitchOutputDevice( |
| 223 device_id, security_origin, | 238 kNonDefaultDeviceId, url::Origin(), |
| 224 base::Bind(&MockSwitchOutputDeviceCallback::Callback, | 239 base::Bind(&MockSwitchOutputDeviceCallback::Callback, |
| 225 base::Unretained(&switch_output_device_callback_))); | 240 base::Unretained(&switch_output_device_callback_))); |
| 226 io_loop_.RunUntilIdle(); | 241 io_loop_.RunUntilIdle(); |
| 227 | 242 |
| 228 // Simulate the reception of a successful response from the browser | 243 // Simulate the reception of a successful response from the browser |
| 229 EXPECT_CALL(switch_output_device_callback_, | 244 EXPECT_CALL(switch_output_device_callback_, |
| 230 Callback(SWITCH_OUTPUT_DEVICE_RESULT_SUCCESS)); | 245 Callback(SWITCH_OUTPUT_DEVICE_RESULT_SUCCESS)); |
| 231 audio_device_->OnOutputDeviceSwitched(request_id, | 246 audio_device_->OnOutputDeviceSwitched(SWITCH_OUTPUT_DEVICE_RESULT_SUCCESS); |
| 232 SWITCH_OUTPUT_DEVICE_RESULT_SUCCESS); | |
| 233 io_loop_.RunUntilIdle(); | 247 io_loop_.RunUntilIdle(); |
| 234 } | 248 } |
| 235 | 249 |
| 236 TEST_P(AudioOutputDeviceTest, Initialize) { | 250 TEST_P(AudioOutputDeviceTest, Initialize) { |
| 237 // Tests that the object can be constructed, initialized and destructed | 251 // Tests that the object can be constructed, initialized and destructed |
| 238 // without having ever been started/stopped. | 252 // without having ever been started. |
| 253 StopAudioDevice(); |
| 239 } | 254 } |
| 240 | 255 |
| 241 // Calls Start() followed by an immediate Stop() and check for the basic message | 256 // Calls Start() followed by an immediate Stop() and check for the basic message |
| 242 // filter messages being sent in that case. | 257 // filter messages being sent in that case. |
| 243 TEST_P(AudioOutputDeviceTest, StartStop) { | 258 TEST_P(AudioOutputDeviceTest, StartStop) { |
| 244 StartAudioDevice(); | 259 StartAudioDevice(); |
| 245 StopAudioDevice(); | 260 StopAudioDevice(); |
| 246 } | 261 } |
| 247 | 262 |
| 248 // AudioOutputDevice supports multiple start/stop sequences. | 263 // AudioOutputDevice supports multiple start/stop sequences. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 276 StopAudioDevice(); | 291 StopAudioDevice(); |
| 277 } | 292 } |
| 278 | 293 |
| 279 // Switch the output device | 294 // Switch the output device |
| 280 TEST_P(AudioOutputDeviceTest, SwitchOutputDevice) { | 295 TEST_P(AudioOutputDeviceTest, SwitchOutputDevice) { |
| 281 StartAudioDevice(); | 296 StartAudioDevice(); |
| 282 SwitchOutputDevice(); | 297 SwitchOutputDevice(); |
| 283 StopAudioDevice(); | 298 StopAudioDevice(); |
| 284 } | 299 } |
| 285 | 300 |
| 301 // Full test with output only with nondefault device. |
| 302 TEST_P(AudioOutputDeviceTest, NonDefaultCreateStream) { |
| 303 SetDevice(kNonDefaultDeviceId); |
| 304 StartAudioDevice(); |
| 305 ExpectRenderCallback(); |
| 306 CreateStream(); |
| 307 WaitUntilRenderCallback(); |
| 308 StopAudioDevice(); |
| 309 } |
| 310 |
| 311 // Multiple start/stop with nondefault device |
| 312 TEST_P(AudioOutputDeviceTest, NonDefaultStartStopStartStop) { |
| 313 SetDevice(kNonDefaultDeviceId); |
| 314 StartAudioDevice(); |
| 315 StopAudioDevice(); |
| 316 |
| 317 EXPECT_CALL(*audio_output_ipc_, |
| 318 RequestDeviceAuthorization(audio_device_.get(), 0, _, _)); |
| 319 StartAudioDevice(); |
| 320 // Simulate reply from browser |
| 321 ReceiveAuthorization(); |
| 322 |
| 323 StopAudioDevice(); |
| 324 } |
| 325 |
| 286 INSTANTIATE_TEST_CASE_P(Render, AudioOutputDeviceTest, Values(false)); | 326 INSTANTIATE_TEST_CASE_P(Render, AudioOutputDeviceTest, Values(false)); |
| 287 | 327 |
| 288 } // namespace media. | 328 } // namespace media. |
| OLD | NEW |