| 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 <string> | 5 #include <string> |
| 6 | 6 |
| 7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 8 #include "base/message_loop/message_loop_proxy.h" | 8 #include "base/message_loop/message_loop_proxy.h" |
| 9 #include "base/run_loop.h" |
| 9 #include "media/audio/audio_manager.h" | 10 #include "media/audio/audio_manager.h" |
| 10 #include "media/audio/audio_manager_base.h" | 11 #include "media/audio/audio_manager_base.h" |
| 11 #include "media/audio/audio_output_dispatcher_impl.h" | 12 #include "media/audio/audio_output_dispatcher_impl.h" |
| 12 #include "media/audio/audio_output_proxy.h" | 13 #include "media/audio/audio_output_proxy.h" |
| 13 #include "media/audio/audio_output_resampler.h" | 14 #include "media/audio/audio_output_resampler.h" |
| 14 #include "media/audio/fake_audio_output_stream.h" | 15 #include "media/audio/fake_audio_output_stream.h" |
| 15 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 18 |
| 18 using ::testing::_; | 19 using ::testing::_; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 29 using media::AudioManager; | 30 using media::AudioManager; |
| 30 using media::AudioManagerBase; | 31 using media::AudioManagerBase; |
| 31 using media::AudioOutputDispatcher; | 32 using media::AudioOutputDispatcher; |
| 32 using media::AudioOutputProxy; | 33 using media::AudioOutputProxy; |
| 33 using media::AudioOutputStream; | 34 using media::AudioOutputStream; |
| 34 using media::AudioParameters; | 35 using media::AudioParameters; |
| 35 using media::FakeAudioOutputStream; | 36 using media::FakeAudioOutputStream; |
| 36 | 37 |
| 37 namespace { | 38 namespace { |
| 38 | 39 |
| 39 static const int kTestCloseDelayMs = 100; | 40 static const int kTestCloseDelayMs = 10; |
| 40 | |
| 41 // Used in the test where we don't want a stream to be closed unexpectedly. | |
| 42 static const int kTestBigCloseDelaySeconds = 1000; | |
| 43 | 41 |
| 44 // Delay between callbacks to AudioSourceCallback::OnMoreData. | 42 // Delay between callbacks to AudioSourceCallback::OnMoreData. |
| 45 static const int kOnMoreDataCallbackDelayMs = 10; | 43 static const int kOnMoreDataCallbackDelayMs = 10; |
| 46 | 44 |
| 47 // Let start run long enough for many OnMoreData callbacks to occur. | 45 // Let start run long enough for many OnMoreData callbacks to occur. |
| 48 static const int kStartRunTimeMs = kOnMoreDataCallbackDelayMs * 10; | 46 static const int kStartRunTimeMs = kOnMoreDataCallbackDelayMs * 10; |
| 49 | 47 |
| 50 class MockAudioOutputStream : public AudioOutputStream { | 48 class MockAudioOutputStream : public AudioOutputStream { |
| 51 public: | 49 public: |
| 52 MockAudioOutputStream(AudioManagerBase* manager, | 50 MockAudioOutputStream(AudioManagerBase* manager, |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 | 136 |
| 139 } // namespace | 137 } // namespace |
| 140 | 138 |
| 141 namespace media { | 139 namespace media { |
| 142 | 140 |
| 143 class AudioOutputProxyTest : public testing::Test { | 141 class AudioOutputProxyTest : public testing::Test { |
| 144 protected: | 142 protected: |
| 145 virtual void SetUp() { | 143 virtual void SetUp() { |
| 146 EXPECT_CALL(manager_, GetMessageLoop()) | 144 EXPECT_CALL(manager_, GetMessageLoop()) |
| 147 .WillRepeatedly(Return(message_loop_.message_loop_proxy())); | 145 .WillRepeatedly(Return(message_loop_.message_loop_proxy())); |
| 146 // Use a low sample rate and large buffer size when testing otherwise the |
| 147 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e., |
| 148 // RunUntilIdle() will never terminate. |
| 149 params_ = AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, |
| 150 CHANNEL_LAYOUT_STEREO, 8000, 16, 2048); |
| 148 InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs)); | 151 InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs)); |
| 149 } | 152 } |
| 150 | 153 |
| 151 virtual void TearDown() { | 154 virtual void TearDown() { |
| 152 // All paused proxies should have been closed at this point. | |
| 153 EXPECT_EQ(0u, dispatcher_impl_->paused_proxies_); | |
| 154 | |
| 155 // This is necessary to free all proxy objects that have been | 155 // This is necessary to free all proxy objects that have been |
| 156 // closed by the test. | 156 // closed by the test. |
| 157 message_loop_.RunUntilIdle(); | 157 message_loop_.RunUntilIdle(); |
| 158 } | 158 } |
| 159 | 159 |
| 160 virtual void InitDispatcher(base::TimeDelta close_delay) { | 160 virtual void InitDispatcher(base::TimeDelta close_delay) { |
| 161 // Use a low sample rate and large buffer size when testing otherwise the | |
| 162 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e., | |
| 163 // RunUntilIdle() will never terminate. | |
| 164 params_ = AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, | |
| 165 CHANNEL_LAYOUT_STEREO, 8000, 16, 2048); | |
| 166 dispatcher_impl_ = new AudioOutputDispatcherImpl(&manager(), | 161 dispatcher_impl_ = new AudioOutputDispatcherImpl(&manager(), |
| 167 params_, | 162 params_, |
| 168 std::string(), | 163 std::string(), |
| 169 std::string(), | 164 std::string(), |
| 170 close_delay); | 165 close_delay); |
| 171 | |
| 172 // Necessary to know how long the dispatcher will wait before posting | |
| 173 // StopStreamTask. | |
| 174 pause_delay_ = dispatcher_impl_->pause_delay_; | |
| 175 } | 166 } |
| 176 | 167 |
| 177 virtual void OnStart() {} | 168 virtual void OnStart() {} |
| 178 | 169 |
| 179 MockAudioManager& manager() { | 170 MockAudioManager& manager() { |
| 180 return manager_; | 171 return manager_; |
| 181 } | 172 } |
| 182 | 173 |
| 183 // Wait for the close timer to fire. | 174 void WaitForCloseTimer(MockAudioOutputStream* stream) { |
| 184 void WaitForCloseTimer(const int timer_delay_ms) { | 175 base::RunLoop run_loop; |
| 185 message_loop_.RunUntilIdle(); // OpenTask() may reset the timer. | 176 EXPECT_CALL(*stream, Close()) |
| 186 base::PlatformThread::Sleep( | 177 .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); |
| 187 base::TimeDelta::FromMilliseconds(timer_delay_ms) * 2); | 178 run_loop.Run(); |
| 188 message_loop_.RunUntilIdle(); | |
| 189 } | 179 } |
| 190 | 180 |
| 191 // Methods that do actual tests. | 181 void CloseAndWaitForCloseTimer(AudioOutputProxy* proxy, |
| 182 MockAudioOutputStream* stream) { |
| 183 // Close the stream and verify it doesn't happen immediately. |
| 184 proxy->Close(); |
| 185 Mock::VerifyAndClear(stream); |
| 186 |
| 187 // Wait for the actual close event to come from the close timer. |
| 188 WaitForCloseTimer(stream); |
| 189 } |
| 190 |
| 191 // Basic Open() and Close() test. |
| 192 void OpenAndClose(AudioOutputDispatcher* dispatcher) { | 192 void OpenAndClose(AudioOutputDispatcher* dispatcher) { |
| 193 MockAudioOutputStream stream(&manager_, params_); | 193 MockAudioOutputStream stream(&manager_, params_); |
| 194 | 194 |
| 195 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 195 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 196 .WillOnce(Return(&stream)); | 196 .WillOnce(Return(&stream)); |
| 197 EXPECT_CALL(stream, Open()) | 197 EXPECT_CALL(stream, Open()) |
| 198 .WillOnce(Return(true)); | 198 .WillOnce(Return(true)); |
| 199 EXPECT_CALL(stream, Close()) | |
| 200 .Times(1); | |
| 201 | 199 |
| 202 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); | 200 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); |
| 203 EXPECT_TRUE(proxy->Open()); | 201 EXPECT_TRUE(proxy->Open()); |
| 204 proxy->Close(); | 202 CloseAndWaitForCloseTimer(proxy, &stream); |
| 205 WaitForCloseTimer(kTestCloseDelayMs); | |
| 206 } | 203 } |
| 207 | 204 |
| 208 // Create a stream, and then calls Start() and Stop(). | 205 // Creates a stream, and then calls Start() and Stop(). |
| 209 void StartAndStop(AudioOutputDispatcher* dispatcher) { | 206 void StartAndStop(AudioOutputDispatcher* dispatcher) { |
| 210 MockAudioOutputStream stream(&manager_, params_); | 207 MockAudioOutputStream stream(&manager_, params_); |
| 211 | 208 |
| 212 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 209 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 213 .WillOnce(Return(&stream)); | 210 .WillOnce(Return(&stream)); |
| 214 EXPECT_CALL(stream, Open()) | 211 EXPECT_CALL(stream, Open()) |
| 215 .WillOnce(Return(true)); | 212 .WillOnce(Return(true)); |
| 216 EXPECT_CALL(stream, SetVolume(_)) | 213 EXPECT_CALL(stream, SetVolume(_)) |
| 217 .Times(1); | 214 .Times(1); |
| 218 EXPECT_CALL(stream, Close()) | |
| 219 .Times(1); | |
| 220 | 215 |
| 221 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); | 216 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); |
| 222 EXPECT_TRUE(proxy->Open()); | 217 EXPECT_TRUE(proxy->Open()); |
| 223 | 218 |
| 224 proxy->Start(&callback_); | 219 proxy->Start(&callback_); |
| 225 OnStart(); | 220 OnStart(); |
| 226 proxy->Stop(); | 221 proxy->Stop(); |
| 227 | 222 |
| 228 proxy->Close(); | 223 CloseAndWaitForCloseTimer(proxy, &stream); |
| 229 WaitForCloseTimer(kTestCloseDelayMs); | |
| 230 EXPECT_TRUE(stream.stop_called()); | 224 EXPECT_TRUE(stream.stop_called()); |
| 231 EXPECT_TRUE(stream.start_called()); | 225 EXPECT_TRUE(stream.start_called()); |
| 232 } | 226 } |
| 233 | 227 |
| 234 // Verify that the stream is closed after Stop is called. | 228 // Verify that the stream is closed after Stop() is called. |
| 235 void CloseAfterStop(AudioOutputDispatcher* dispatcher) { | 229 void CloseAfterStop(AudioOutputDispatcher* dispatcher) { |
| 236 MockAudioOutputStream stream(&manager_, params_); | 230 MockAudioOutputStream stream(&manager_, params_); |
| 237 | 231 |
| 238 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 232 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 239 .WillOnce(Return(&stream)); | 233 .WillOnce(Return(&stream)); |
| 240 EXPECT_CALL(stream, Open()) | 234 EXPECT_CALL(stream, Open()) |
| 241 .WillOnce(Return(true)); | 235 .WillOnce(Return(true)); |
| 242 EXPECT_CALL(stream, SetVolume(_)) | 236 EXPECT_CALL(stream, SetVolume(_)) |
| 243 .Times(1); | 237 .Times(1); |
| 244 EXPECT_CALL(stream, Close()) | |
| 245 .Times(1); | |
| 246 | 238 |
| 247 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); | 239 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); |
| 248 EXPECT_TRUE(proxy->Open()); | 240 EXPECT_TRUE(proxy->Open()); |
| 249 | 241 |
| 250 proxy->Start(&callback_); | 242 proxy->Start(&callback_); |
| 251 OnStart(); | 243 OnStart(); |
| 252 proxy->Stop(); | 244 proxy->Stop(); |
| 253 | 245 |
| 254 // Wait for StopStream() to post StopStreamTask(). | 246 // Wait for the close timer to fire after StopStream(). |
| 255 base::PlatformThread::Sleep(pause_delay_ * 2); | 247 WaitForCloseTimer(&stream); |
| 256 WaitForCloseTimer(kTestCloseDelayMs); | |
| 257 | |
| 258 // Verify expectation before calling Close(). | |
| 259 Mock::VerifyAndClear(&stream); | |
| 260 | |
| 261 proxy->Close(); | 248 proxy->Close(); |
| 262 EXPECT_TRUE(stream.stop_called()); | 249 EXPECT_TRUE(stream.stop_called()); |
| 263 EXPECT_TRUE(stream.start_called()); | 250 EXPECT_TRUE(stream.start_called()); |
| 264 } | 251 } |
| 265 | 252 |
| 266 // Create two streams, but don't start them. Only one device must be open. | 253 // Create two streams, but don't start them. Only one device must be opened. |
| 267 void TwoStreams(AudioOutputDispatcher* dispatcher) { | 254 void TwoStreams(AudioOutputDispatcher* dispatcher) { |
| 268 MockAudioOutputStream stream(&manager_, params_); | 255 MockAudioOutputStream stream(&manager_, params_); |
| 269 | 256 |
| 270 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 257 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 271 .WillOnce(Return(&stream)); | 258 .WillOnce(Return(&stream)); |
| 272 EXPECT_CALL(stream, Open()) | 259 EXPECT_CALL(stream, Open()) |
| 273 .WillOnce(Return(true)); | 260 .WillOnce(Return(true)); |
| 274 EXPECT_CALL(stream, Close()) | |
| 275 .Times(1); | |
| 276 | 261 |
| 277 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); | 262 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); |
| 278 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); | 263 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); |
| 279 EXPECT_TRUE(proxy1->Open()); | 264 EXPECT_TRUE(proxy1->Open()); |
| 280 EXPECT_TRUE(proxy2->Open()); | 265 EXPECT_TRUE(proxy2->Open()); |
| 281 proxy1->Close(); | 266 proxy1->Close(); |
| 282 proxy2->Close(); | 267 CloseAndWaitForCloseTimer(proxy2, &stream); |
| 283 WaitForCloseTimer(kTestCloseDelayMs); | |
| 284 EXPECT_FALSE(stream.stop_called()); | 268 EXPECT_FALSE(stream.stop_called()); |
| 285 EXPECT_FALSE(stream.start_called()); | 269 EXPECT_FALSE(stream.start_called()); |
| 286 } | 270 } |
| 287 | 271 |
| 288 // Open() method failed. | 272 // Open() method failed. |
| 289 void OpenFailed(AudioOutputDispatcher* dispatcher) { | 273 void OpenFailed(AudioOutputDispatcher* dispatcher) { |
| 290 MockAudioOutputStream stream(&manager_, params_); | 274 MockAudioOutputStream stream(&manager_, params_); |
| 291 | 275 |
| 292 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 276 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 293 .WillOnce(Return(&stream)); | 277 .WillOnce(Return(&stream)); |
| 294 EXPECT_CALL(stream, Open()) | 278 EXPECT_CALL(stream, Open()) |
| 295 .WillOnce(Return(false)); | 279 .WillOnce(Return(false)); |
| 296 EXPECT_CALL(stream, Close()) | 280 EXPECT_CALL(stream, Close()) |
| 297 .Times(1); | 281 .Times(1); |
| 298 | 282 |
| 299 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); | 283 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); |
| 300 EXPECT_FALSE(proxy->Open()); | 284 EXPECT_FALSE(proxy->Open()); |
| 301 proxy->Close(); | 285 proxy->Close(); |
| 302 WaitForCloseTimer(kTestCloseDelayMs); | |
| 303 EXPECT_FALSE(stream.stop_called()); | 286 EXPECT_FALSE(stream.stop_called()); |
| 304 EXPECT_FALSE(stream.start_called()); | 287 EXPECT_FALSE(stream.start_called()); |
| 305 } | 288 } |
| 306 | 289 |
| 307 void CreateAndWait(AudioOutputDispatcher* dispatcher) { | 290 void CreateAndWait(AudioOutputDispatcher* dispatcher) { |
| 308 MockAudioOutputStream stream(&manager_, params_); | 291 MockAudioOutputStream stream(&manager_, params_); |
| 309 | 292 |
| 310 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 293 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 311 .WillOnce(Return(&stream)); | 294 .WillOnce(Return(&stream)); |
| 312 EXPECT_CALL(stream, Open()) | 295 EXPECT_CALL(stream, Open()) |
| 313 .WillOnce(Return(true)); | 296 .WillOnce(Return(true)); |
| 314 EXPECT_CALL(stream, Close()) | |
| 315 .Times(1); | |
| 316 | 297 |
| 317 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); | 298 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); |
| 318 EXPECT_TRUE(proxy->Open()); | 299 EXPECT_TRUE(proxy->Open()); |
| 319 | 300 |
| 320 // Simulate a delay. | 301 WaitForCloseTimer(&stream); |
| 321 base::PlatformThread::Sleep( | |
| 322 base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2); | |
| 323 message_loop_.RunUntilIdle(); | |
| 324 | |
| 325 // Verify expectation before calling Close(). | |
| 326 Mock::VerifyAndClear(&stream); | |
| 327 | |
| 328 proxy->Close(); | 302 proxy->Close(); |
| 329 EXPECT_FALSE(stream.stop_called()); | 303 EXPECT_FALSE(stream.stop_called()); |
| 330 EXPECT_FALSE(stream.start_called()); | 304 EXPECT_FALSE(stream.start_called()); |
| 331 } | 305 } |
| 332 | 306 |
| 333 void TwoStreams_OnePlaying(AudioOutputDispatcher* dispatcher) { | 307 void OneStream_TwoPlays(AudioOutputDispatcher* dispatcher) { |
| 334 MockAudioOutputStream stream1(&manager_, params_); | 308 MockAudioOutputStream stream(&manager_, params_); |
| 335 MockAudioOutputStream stream2(&manager_, params_); | |
| 336 | 309 |
| 337 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 310 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 338 .WillOnce(Return(&stream1)) | 311 .WillOnce(Return(&stream)); |
| 339 .WillOnce(Return(&stream2)); | |
| 340 | 312 |
| 341 EXPECT_CALL(stream1, Open()) | 313 EXPECT_CALL(stream, Open()) |
| 342 .WillOnce(Return(true)); | 314 .WillOnce(Return(true)); |
| 343 EXPECT_CALL(stream1, SetVolume(_)) | 315 EXPECT_CALL(stream, SetVolume(_)) |
| 344 .Times(1); | 316 .Times(2); |
| 345 EXPECT_CALL(stream1, Close()) | |
| 346 .Times(1); | |
| 347 | |
| 348 EXPECT_CALL(stream2, Open()) | |
| 349 .WillOnce(Return(true)); | |
| 350 EXPECT_CALL(stream2, Close()) | |
| 351 .Times(1); | |
| 352 | 317 |
| 353 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); | 318 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); |
| 354 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); | |
| 355 EXPECT_TRUE(proxy1->Open()); | 319 EXPECT_TRUE(proxy1->Open()); |
| 356 EXPECT_TRUE(proxy2->Open()); | |
| 357 | 320 |
| 358 proxy1->Start(&callback_); | 321 proxy1->Start(&callback_); |
| 359 message_loop_.RunUntilIdle(); | |
| 360 OnStart(); | 322 OnStart(); |
| 361 proxy1->Stop(); | 323 proxy1->Stop(); |
| 362 | 324 |
| 325 // The stream should now be idle and get reused by |proxy2|. |
| 326 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); |
| 327 EXPECT_TRUE(proxy2->Open()); |
| 328 proxy2->Start(&callback_); |
| 329 OnStart(); |
| 330 proxy2->Stop(); |
| 331 |
| 363 proxy1->Close(); | 332 proxy1->Close(); |
| 364 proxy2->Close(); | 333 CloseAndWaitForCloseTimer(proxy2, &stream); |
| 365 EXPECT_TRUE(stream1.stop_called()); | 334 EXPECT_TRUE(stream.stop_called()); |
| 366 EXPECT_TRUE(stream1.start_called()); | 335 EXPECT_TRUE(stream.start_called()); |
| 367 EXPECT_FALSE(stream2.stop_called()); | |
| 368 EXPECT_FALSE(stream2.start_called()); | |
| 369 } | 336 } |
| 370 | 337 |
| 371 void TwoStreams_BothPlaying(AudioOutputDispatcher* dispatcher) { | 338 void TwoStreams_BothPlaying(AudioOutputDispatcher* dispatcher) { |
| 372 MockAudioOutputStream stream1(&manager_, params_); | 339 MockAudioOutputStream stream1(&manager_, params_); |
| 373 MockAudioOutputStream stream2(&manager_, params_); | 340 MockAudioOutputStream stream2(&manager_, params_); |
| 374 | 341 |
| 375 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 342 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 376 .WillOnce(Return(&stream1)) | 343 .WillOnce(Return(&stream1)) |
| 377 .WillOnce(Return(&stream2)); | 344 .WillOnce(Return(&stream2)); |
| 378 | 345 |
| 379 EXPECT_CALL(stream1, Open()) | 346 EXPECT_CALL(stream1, Open()) |
| 380 .WillOnce(Return(true)); | 347 .WillOnce(Return(true)); |
| 381 EXPECT_CALL(stream1, SetVolume(_)) | 348 EXPECT_CALL(stream1, SetVolume(_)) |
| 382 .Times(1); | 349 .Times(1); |
| 383 EXPECT_CALL(stream1, Close()) | |
| 384 .Times(1); | |
| 385 | 350 |
| 386 EXPECT_CALL(stream2, Open()) | 351 EXPECT_CALL(stream2, Open()) |
| 387 .WillOnce(Return(true)); | 352 .WillOnce(Return(true)); |
| 388 EXPECT_CALL(stream2, SetVolume(_)) | 353 EXPECT_CALL(stream2, SetVolume(_)) |
| 389 .Times(1); | 354 .Times(1); |
| 390 EXPECT_CALL(stream2, Close()) | |
| 391 .Times(1); | |
| 392 | 355 |
| 393 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); | 356 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); |
| 394 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); | 357 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); |
| 395 EXPECT_TRUE(proxy1->Open()); | 358 EXPECT_TRUE(proxy1->Open()); |
| 396 EXPECT_TRUE(proxy2->Open()); | 359 EXPECT_TRUE(proxy2->Open()); |
| 397 | 360 |
| 398 proxy1->Start(&callback_); | 361 proxy1->Start(&callback_); |
| 399 proxy2->Start(&callback_); | 362 proxy2->Start(&callback_); |
| 400 OnStart(); | 363 OnStart(); |
| 401 proxy1->Stop(); | 364 proxy1->Stop(); |
| 365 CloseAndWaitForCloseTimer(proxy1, &stream1); |
| 366 |
| 402 proxy2->Stop(); | 367 proxy2->Stop(); |
| 368 CloseAndWaitForCloseTimer(proxy2, &stream2); |
| 403 | 369 |
| 404 proxy1->Close(); | |
| 405 proxy2->Close(); | |
| 406 EXPECT_TRUE(stream1.stop_called()); | 370 EXPECT_TRUE(stream1.stop_called()); |
| 407 EXPECT_TRUE(stream1.start_called()); | 371 EXPECT_TRUE(stream1.start_called()); |
| 408 EXPECT_TRUE(stream2.stop_called()); | 372 EXPECT_TRUE(stream2.stop_called()); |
| 409 EXPECT_TRUE(stream2.start_called()); | 373 EXPECT_TRUE(stream2.start_called()); |
| 410 } | 374 } |
| 411 | 375 |
| 412 void StartFailed(AudioOutputDispatcher* dispatcher) { | 376 void StartFailed(AudioOutputDispatcher* dispatcher) { |
| 413 MockAudioOutputStream stream(&manager_, params_); | 377 MockAudioOutputStream stream(&manager_, params_); |
| 414 | 378 |
| 415 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 379 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 416 .WillOnce(Return(&stream)); | 380 .WillOnce(Return(&stream)); |
| 417 EXPECT_CALL(stream, Open()) | 381 EXPECT_CALL(stream, Open()) |
| 418 .WillOnce(Return(true)); | 382 .WillOnce(Return(true)); |
| 419 EXPECT_CALL(stream, Close()) | |
| 420 .Times(1); | |
| 421 | 383 |
| 422 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); | 384 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); |
| 423 EXPECT_TRUE(proxy->Open()); | 385 EXPECT_TRUE(proxy->Open()); |
| 424 | 386 |
| 425 // Simulate a delay. | 387 WaitForCloseTimer(&stream); |
| 426 base::PlatformThread::Sleep( | |
| 427 base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2); | |
| 428 message_loop_.RunUntilIdle(); | |
| 429 | |
| 430 // Verify expectation before calling Close(). | |
| 431 Mock::VerifyAndClear(&stream); | |
| 432 | 388 |
| 433 // |stream| is closed at this point. Start() should reopen it again. | 389 // |stream| is closed at this point. Start() should reopen it again. |
| 434 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 390 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 435 .Times(2) | 391 .Times(2) |
| 436 .WillRepeatedly(Return(reinterpret_cast<AudioOutputStream*>(NULL))); | 392 .WillRepeatedly(Return(reinterpret_cast<AudioOutputStream*>(NULL))); |
| 437 | 393 |
| 438 EXPECT_CALL(callback_, OnError(_)) | 394 EXPECT_CALL(callback_, OnError(_)) |
| 439 .Times(2); | 395 .Times(2); |
| 440 | 396 |
| 441 proxy->Start(&callback_); | 397 proxy->Start(&callback_); |
| 442 | 398 |
| 443 // Double Start() in the error case should be allowed since it's possible a | 399 // Double Start() in the error case should be allowed since it's possible a |
| 444 // callback may not have had time to process the OnError() in between. | 400 // callback may not have had time to process the OnError() in between. |
| 445 proxy->Stop(); | 401 proxy->Stop(); |
| 446 proxy->Start(&callback_); | 402 proxy->Start(&callback_); |
| 447 | 403 |
| 448 Mock::VerifyAndClear(&callback_); | 404 Mock::VerifyAndClear(&callback_); |
| 449 | 405 |
| 450 proxy->Close(); | 406 proxy->Close(); |
| 451 } | 407 } |
| 452 | 408 |
| 453 base::MessageLoop message_loop_; | 409 base::MessageLoop message_loop_; |
| 454 scoped_refptr<AudioOutputDispatcherImpl> dispatcher_impl_; | 410 scoped_refptr<AudioOutputDispatcherImpl> dispatcher_impl_; |
| 455 base::TimeDelta pause_delay_; | |
| 456 MockAudioManager manager_; | 411 MockAudioManager manager_; |
| 457 MockAudioSourceCallback callback_; | 412 MockAudioSourceCallback callback_; |
| 458 AudioParameters params_; | 413 AudioParameters params_; |
| 459 }; | 414 }; |
| 460 | 415 |
| 461 class AudioOutputResamplerTest : public AudioOutputProxyTest { | 416 class AudioOutputResamplerTest : public AudioOutputProxyTest { |
| 462 public: | 417 public: |
| 463 virtual void TearDown() { | 418 virtual void TearDown() { |
| 464 AudioOutputProxyTest::TearDown(); | 419 AudioOutputProxyTest::TearDown(); |
| 465 } | 420 } |
| 466 | 421 |
| 467 virtual void InitDispatcher(base::TimeDelta close_delay) OVERRIDE { | 422 virtual void InitDispatcher(base::TimeDelta close_delay) OVERRIDE { |
| 468 AudioOutputProxyTest::InitDispatcher(close_delay); | |
| 469 // Use a low sample rate and large buffer size when testing otherwise the | 423 // Use a low sample rate and large buffer size when testing otherwise the |
| 470 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e., | 424 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e., |
| 471 // RunUntilIdle() will never terminate. | 425 // RunUntilIdle() will never terminate. |
| 472 resampler_params_ = AudioParameters( | 426 resampler_params_ = AudioParameters( |
| 473 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, | 427 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, |
| 474 16000, 16, 1024); | 428 16000, 16, 1024); |
| 475 resampler_ = new AudioOutputResampler( | 429 resampler_ = new AudioOutputResampler( |
| 476 &manager(), params_, resampler_params_, std::string(), std::string(), | 430 &manager(), params_, resampler_params_, std::string(), std::string(), |
| 477 close_delay); | 431 close_delay); |
| 478 } | 432 } |
| 479 | 433 |
| 480 virtual void OnStart() OVERRIDE { | 434 virtual void OnStart() OVERRIDE { |
| 481 // Let start run for a bit. | 435 // Let Start() run for a bit. |
| 482 message_loop_.RunUntilIdle(); | 436 base::RunLoop run_loop; |
| 483 base::PlatformThread::Sleep( | 437 message_loop_.PostDelayedTask( |
| 438 FROM_HERE, |
| 439 run_loop.QuitClosure(), |
| 484 base::TimeDelta::FromMilliseconds(kStartRunTimeMs)); | 440 base::TimeDelta::FromMilliseconds(kStartRunTimeMs)); |
| 441 run_loop.Run(); |
| 485 } | 442 } |
| 486 | 443 |
| 487 protected: | 444 protected: |
| 488 AudioParameters resampler_params_; | 445 AudioParameters resampler_params_; |
| 489 scoped_refptr<AudioOutputResampler> resampler_; | 446 scoped_refptr<AudioOutputResampler> resampler_; |
| 490 }; | 447 }; |
| 491 | 448 |
| 492 TEST_F(AudioOutputProxyTest, CreateAndClose) { | 449 TEST_F(AudioOutputProxyTest, CreateAndClose) { |
| 493 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_.get()); | 450 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_); |
| 494 proxy->Close(); | 451 proxy->Close(); |
| 495 } | 452 } |
| 496 | 453 |
| 497 TEST_F(AudioOutputResamplerTest, CreateAndClose) { | 454 TEST_F(AudioOutputResamplerTest, CreateAndClose) { |
| 498 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); | 455 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); |
| 499 proxy->Close(); | 456 proxy->Close(); |
| 500 } | 457 } |
| 501 | 458 |
| 502 TEST_F(AudioOutputProxyTest, OpenAndClose) { | 459 TEST_F(AudioOutputProxyTest, OpenAndClose) { |
| 503 OpenAndClose(dispatcher_impl_.get()); | 460 OpenAndClose(dispatcher_impl_); |
| 504 } | 461 } |
| 505 | 462 |
| 506 TEST_F(AudioOutputResamplerTest, OpenAndClose) { | 463 TEST_F(AudioOutputResamplerTest, OpenAndClose) { |
| 507 OpenAndClose(resampler_.get()); | 464 OpenAndClose(resampler_); |
| 508 } | 465 } |
| 509 | 466 |
| 510 // Create a stream, and verify that it is closed after kTestCloseDelayMs. | 467 // Create a stream, and verify that it is closed after kTestCloseDelayMs. |
| 511 // if it doesn't start playing. | 468 // if it doesn't start playing. |
| 512 TEST_F(AudioOutputProxyTest, CreateAndWait) { | 469 TEST_F(AudioOutputProxyTest, CreateAndWait) { |
| 513 CreateAndWait(dispatcher_impl_.get()); | 470 CreateAndWait(dispatcher_impl_); |
| 514 } | 471 } |
| 515 | 472 |
| 516 // Create a stream, and verify that it is closed after kTestCloseDelayMs. | 473 // Create a stream, and verify that it is closed after kTestCloseDelayMs. |
| 517 // if it doesn't start playing. | 474 // if it doesn't start playing. |
| 518 TEST_F(AudioOutputResamplerTest, CreateAndWait) { | 475 TEST_F(AudioOutputResamplerTest, CreateAndWait) { |
| 519 CreateAndWait(resampler_.get()); | 476 CreateAndWait(resampler_); |
| 520 } | 477 } |
| 521 | 478 |
| 522 TEST_F(AudioOutputProxyTest, StartAndStop) { | 479 TEST_F(AudioOutputProxyTest, StartAndStop) { |
| 523 StartAndStop(dispatcher_impl_.get()); | 480 StartAndStop(dispatcher_impl_); |
| 524 } | 481 } |
| 525 | 482 |
| 526 TEST_F(AudioOutputResamplerTest, StartAndStop) { | 483 TEST_F(AudioOutputResamplerTest, StartAndStop) { |
| 527 StartAndStop(resampler_.get()); | 484 StartAndStop(resampler_); |
| 528 } | 485 } |
| 529 | 486 |
| 530 TEST_F(AudioOutputProxyTest, CloseAfterStop) { | 487 TEST_F(AudioOutputProxyTest, CloseAfterStop) { |
| 531 CloseAfterStop(dispatcher_impl_.get()); | 488 CloseAfterStop(dispatcher_impl_); |
| 532 } | 489 } |
| 533 | 490 |
| 534 TEST_F(AudioOutputResamplerTest, CloseAfterStop) { | 491 TEST_F(AudioOutputResamplerTest, CloseAfterStop) { |
| 535 CloseAfterStop(resampler_.get()); | 492 CloseAfterStop(resampler_); |
| 536 } | 493 } |
| 537 | 494 |
| 538 TEST_F(AudioOutputProxyTest, TwoStreams) { TwoStreams(dispatcher_impl_.get()); } | 495 TEST_F(AudioOutputProxyTest, TwoStreams) { TwoStreams(dispatcher_impl_); } |
| 539 | 496 |
| 540 TEST_F(AudioOutputResamplerTest, TwoStreams) { TwoStreams(resampler_.get()); } | 497 TEST_F(AudioOutputResamplerTest, TwoStreams) { TwoStreams(resampler_); } |
| 541 | 498 |
| 542 // Two streams: verify that second stream is allocated when the first | 499 // Two streams: verify that second stream is allocated when the first |
| 543 // starts playing. | 500 // starts playing. |
| 544 TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying) { | 501 TEST_F(AudioOutputProxyTest, OneStream_TwoPlays) { |
| 545 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); | 502 OneStream_TwoPlays(dispatcher_impl_); |
| 546 TwoStreams_OnePlaying(dispatcher_impl_.get()); | |
| 547 } | 503 } |
| 548 | 504 |
| 549 TEST_F(AudioOutputResamplerTest, TwoStreams_OnePlaying) { | 505 TEST_F(AudioOutputResamplerTest, OneStream_TwoPlays) { |
| 550 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); | 506 OneStream_TwoPlays(resampler_); |
| 551 TwoStreams_OnePlaying(resampler_.get()); | |
| 552 } | 507 } |
| 553 | 508 |
| 554 // Two streams, both are playing. Dispatcher should not open a third stream. | 509 // Two streams, both are playing. Dispatcher should not open a third stream. |
| 555 TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) { | 510 TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) { |
| 556 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); | 511 TwoStreams_BothPlaying(dispatcher_impl_); |
| 557 TwoStreams_BothPlaying(dispatcher_impl_.get()); | |
| 558 } | 512 } |
| 559 | 513 |
| 560 TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) { | 514 TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) { |
| 561 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); | 515 TwoStreams_BothPlaying(resampler_); |
| 562 TwoStreams_BothPlaying(resampler_.get()); | |
| 563 } | 516 } |
| 564 | 517 |
| 565 TEST_F(AudioOutputProxyTest, OpenFailed) { OpenFailed(dispatcher_impl_.get()); } | 518 TEST_F(AudioOutputProxyTest, OpenFailed) { OpenFailed(dispatcher_impl_); } |
| 566 | 519 |
| 567 // Start() method failed. | 520 // Start() method failed. |
| 568 TEST_F(AudioOutputProxyTest, StartFailed) { | 521 TEST_F(AudioOutputProxyTest, StartFailed) { |
| 569 StartFailed(dispatcher_impl_.get()); | 522 StartFailed(dispatcher_impl_); |
| 570 } | 523 } |
| 571 | 524 |
| 572 TEST_F(AudioOutputResamplerTest, StartFailed) { StartFailed(resampler_.get()); } | 525 TEST_F(AudioOutputResamplerTest, StartFailed) { StartFailed(resampler_); } |
| 573 | 526 |
| 574 // Simulate AudioOutputStream::Create() failure with a low latency stream and | 527 // Simulate AudioOutputStream::Create() failure with a low latency stream and |
| 575 // ensure AudioOutputResampler falls back to the high latency path. | 528 // ensure AudioOutputResampler falls back to the high latency path. |
| 576 TEST_F(AudioOutputResamplerTest, LowLatencyCreateFailedFallback) { | 529 TEST_F(AudioOutputResamplerTest, LowLatencyCreateFailedFallback) { |
| 577 MockAudioOutputStream stream(&manager_, params_); | 530 MockAudioOutputStream stream(&manager_, params_); |
| 578 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 531 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 579 .Times(2) | 532 .Times(2) |
| 580 .WillOnce(Return(static_cast<AudioOutputStream*>(NULL))) | 533 .WillOnce(Return(static_cast<AudioOutputStream*>(NULL))) |
| 581 .WillRepeatedly(Return(&stream)); | 534 .WillRepeatedly(Return(&stream)); |
| 582 EXPECT_CALL(stream, Open()) | 535 EXPECT_CALL(stream, Open()) |
| 583 .WillOnce(Return(true)); | 536 .WillOnce(Return(true)); |
| 584 EXPECT_CALL(stream, Close()) | |
| 585 .Times(1); | |
| 586 | 537 |
| 587 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); | 538 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); |
| 588 EXPECT_TRUE(proxy->Open()); | 539 EXPECT_TRUE(proxy->Open()); |
| 589 proxy->Close(); | 540 CloseAndWaitForCloseTimer(proxy, &stream); |
| 590 WaitForCloseTimer(kTestCloseDelayMs); | |
| 591 } | 541 } |
| 592 | 542 |
| 593 // Simulate AudioOutputStream::Open() failure with a low latency stream and | 543 // Simulate AudioOutputStream::Open() failure with a low latency stream and |
| 594 // ensure AudioOutputResampler falls back to the high latency path. | 544 // ensure AudioOutputResampler falls back to the high latency path. |
| 595 TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) { | 545 TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) { |
| 596 MockAudioOutputStream failed_stream(&manager_, params_); | 546 MockAudioOutputStream failed_stream(&manager_, params_); |
| 597 MockAudioOutputStream okay_stream(&manager_, params_); | 547 MockAudioOutputStream okay_stream(&manager_, params_); |
| 598 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 548 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 599 .Times(2) | 549 .Times(2) |
| 600 .WillOnce(Return(&failed_stream)) | 550 .WillOnce(Return(&failed_stream)) |
| 601 .WillRepeatedly(Return(&okay_stream)); | 551 .WillRepeatedly(Return(&okay_stream)); |
| 602 EXPECT_CALL(failed_stream, Open()) | 552 EXPECT_CALL(failed_stream, Open()) |
| 603 .WillOnce(Return(false)); | 553 .WillOnce(Return(false)); |
| 604 EXPECT_CALL(failed_stream, Close()) | 554 EXPECT_CALL(failed_stream, Close()) |
| 605 .Times(1); | 555 .Times(1); |
| 606 EXPECT_CALL(okay_stream, Open()) | 556 EXPECT_CALL(okay_stream, Open()) |
| 607 .WillOnce(Return(true)); | 557 .WillOnce(Return(true)); |
| 608 EXPECT_CALL(okay_stream, Close()) | |
| 609 .Times(1); | |
| 610 | 558 |
| 611 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); | 559 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); |
| 612 EXPECT_TRUE(proxy->Open()); | 560 EXPECT_TRUE(proxy->Open()); |
| 613 proxy->Close(); | 561 CloseAndWaitForCloseTimer(proxy, &okay_stream); |
| 614 WaitForCloseTimer(kTestCloseDelayMs); | |
| 615 } | 562 } |
| 616 | 563 |
| 617 // Simulate failures to open both the low latency and the fallback high latency | 564 // Simulate failures to open both the low latency and the fallback high latency |
| 618 // stream and ensure AudioOutputResampler falls back to a fake stream. | 565 // stream and ensure AudioOutputResampler falls back to a fake stream. |
| 619 TEST_F(AudioOutputResamplerTest, HighLatencyFallbackFailed) { | 566 TEST_F(AudioOutputResamplerTest, HighLatencyFallbackFailed) { |
| 620 MockAudioOutputStream okay_stream(&manager_, params_); | 567 MockAudioOutputStream okay_stream(&manager_, params_); |
| 621 | 568 |
| 622 // Only Windows has a high latency output driver that is not the same as the low | 569 // Only Windows has a high latency output driver that is not the same as the low |
| 623 // latency path. | 570 // latency path. |
| 624 #if defined(OS_WIN) | 571 #if defined(OS_WIN) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 635 EXPECT_CALL(manager(), MakeAudioOutputStream(AllOf( | 582 EXPECT_CALL(manager(), MakeAudioOutputStream(AllOf( |
| 636 testing::Property(&AudioParameters::format, AudioParameters::AUDIO_FAKE), | 583 testing::Property(&AudioParameters::format, AudioParameters::AUDIO_FAKE), |
| 637 testing::Property(&AudioParameters::sample_rate, params_.sample_rate()), | 584 testing::Property(&AudioParameters::sample_rate, params_.sample_rate()), |
| 638 testing::Property( | 585 testing::Property( |
| 639 &AudioParameters::frames_per_buffer, params_.frames_per_buffer())), | 586 &AudioParameters::frames_per_buffer, params_.frames_per_buffer())), |
| 640 _, _)) | 587 _, _)) |
| 641 .Times(1) | 588 .Times(1) |
| 642 .WillOnce(Return(&okay_stream)); | 589 .WillOnce(Return(&okay_stream)); |
| 643 EXPECT_CALL(okay_stream, Open()) | 590 EXPECT_CALL(okay_stream, Open()) |
| 644 .WillOnce(Return(true)); | 591 .WillOnce(Return(true)); |
| 645 EXPECT_CALL(okay_stream, Close()) | |
| 646 .Times(1); | |
| 647 | 592 |
| 648 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); | 593 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); |
| 649 EXPECT_TRUE(proxy->Open()); | 594 EXPECT_TRUE(proxy->Open()); |
| 650 proxy->Close(); | 595 CloseAndWaitForCloseTimer(proxy, &okay_stream); |
| 651 WaitForCloseTimer(kTestCloseDelayMs); | |
| 652 } | 596 } |
| 653 | 597 |
| 654 // Simulate failures to open both the low latency, the fallback high latency | 598 // Simulate failures to open both the low latency, the fallback high latency |
| 655 // stream, and the fake audio output stream and ensure AudioOutputResampler | 599 // stream, and the fake audio output stream and ensure AudioOutputResampler |
| 656 // terminates normally. | 600 // terminates normally. |
| 657 TEST_F(AudioOutputResamplerTest, AllFallbackFailed) { | 601 TEST_F(AudioOutputResamplerTest, AllFallbackFailed) { |
| 658 // Only Windows has a high latency output driver that is not the same as the low | 602 // Only Windows has a high latency output driver that is not the same as the low |
| 659 // latency path. | 603 // latency path. |
| 660 #if defined(OS_WIN) | 604 #if defined(OS_WIN) |
| 661 static const int kFallbackCount = 3; | 605 static const int kFallbackCount = 3; |
| 662 #else | 606 #else |
| 663 static const int kFallbackCount = 2; | 607 static const int kFallbackCount = 2; |
| 664 #endif | 608 #endif |
| 665 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 609 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 666 .Times(kFallbackCount) | 610 .Times(kFallbackCount) |
| 667 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); | 611 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); |
| 668 | 612 |
| 669 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); | 613 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); |
| 670 EXPECT_FALSE(proxy->Open()); | 614 EXPECT_FALSE(proxy->Open()); |
| 671 proxy->Close(); | 615 proxy->Close(); |
| 672 WaitForCloseTimer(kTestCloseDelayMs); | |
| 673 } | 616 } |
| 674 | 617 |
| 675 // Simulate an eventual OpenStream() failure; i.e. successful OpenStream() calls | 618 // Simulate an eventual OpenStream() failure; i.e. successful OpenStream() calls |
| 676 // eventually followed by one which fails; root cause of http://crbug.com/150619 | 619 // eventually followed by one which fails; root cause of http://crbug.com/150619 |
| 677 TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) { | 620 TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) { |
| 678 MockAudioOutputStream stream1(&manager_, params_); | 621 MockAudioOutputStream stream1(&manager_, params_); |
| 679 MockAudioOutputStream stream2(&manager_, params_); | 622 MockAudioOutputStream stream2(&manager_, params_); |
| 680 MockAudioOutputStream stream3(&manager_, params_); | |
| 681 | 623 |
| 682 // Setup the mock such that all three streams are successfully created. | 624 // Setup the mock such that all three streams are successfully created. |
| 683 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 625 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 684 .WillOnce(Return(&stream1)) | 626 .WillOnce(Return(&stream1)) |
| 685 .WillOnce(Return(&stream2)) | 627 .WillOnce(Return(&stream2)) |
| 686 .WillOnce(Return(&stream3)) | |
| 687 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); | 628 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); |
| 688 | 629 |
| 689 // Stream1 should be able to successfully open and start. | 630 // Stream1 should be able to successfully open and start. |
| 690 EXPECT_CALL(stream1, Open()) | 631 EXPECT_CALL(stream1, Open()) |
| 691 .WillOnce(Return(true)); | 632 .WillOnce(Return(true)); |
| 692 EXPECT_CALL(stream1, Close()) | |
| 693 .Times(1); | |
| 694 EXPECT_CALL(stream1, SetVolume(_)) | 633 EXPECT_CALL(stream1, SetVolume(_)) |
| 695 .Times(1); | 634 .Times(1); |
| 696 | 635 |
| 697 // Stream2 should also be able to successfully open and start. | 636 // Stream2 should also be able to successfully open and start. |
| 698 EXPECT_CALL(stream2, Open()) | 637 EXPECT_CALL(stream2, Open()) |
| 699 .WillOnce(Return(true)); | 638 .WillOnce(Return(true)); |
| 700 EXPECT_CALL(stream2, Close()) | |
| 701 .Times(1); | |
| 702 EXPECT_CALL(stream2, SetVolume(_)) | 639 EXPECT_CALL(stream2, SetVolume(_)) |
| 703 .Times(1); | 640 .Times(1); |
| 704 | 641 |
| 705 // Stream3 should fail on Open() (yet still be closed since | |
| 706 // MakeAudioOutputStream returned a valid AudioOutputStream object). | |
| 707 EXPECT_CALL(stream3, Open()) | |
| 708 .WillOnce(Return(false)); | |
| 709 EXPECT_CALL(stream3, Close()) | |
| 710 .Times(1); | |
| 711 | |
| 712 // Open and start the first proxy and stream. | 642 // Open and start the first proxy and stream. |
| 713 AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_.get()); | 643 AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_); |
| 714 EXPECT_TRUE(proxy1->Open()); | 644 EXPECT_TRUE(proxy1->Open()); |
| 715 proxy1->Start(&callback_); | 645 proxy1->Start(&callback_); |
| 716 OnStart(); | 646 OnStart(); |
| 717 | 647 |
| 718 // Open and start the second proxy and stream. | 648 // Open and start the second proxy and stream. |
| 719 AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_.get()); | 649 AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_); |
| 720 EXPECT_TRUE(proxy2->Open()); | 650 EXPECT_TRUE(proxy2->Open()); |
| 721 proxy2->Start(&callback_); | 651 proxy2->Start(&callback_); |
| 722 OnStart(); | 652 OnStart(); |
| 723 | 653 |
| 724 // Attempt to open the third stream which should fail. | 654 // Attempt to open the third stream which should fail. |
| 725 AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_.get()); | 655 AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_); |
| 726 EXPECT_FALSE(proxy3->Open()); | 656 EXPECT_FALSE(proxy3->Open()); |
| 657 proxy3->Close(); |
| 727 | 658 |
| 728 // Perform the required Stop()/Close() shutdown dance for each proxy. Under | 659 // Perform the required Stop()/Close() shutdown dance for each proxy. Under |
| 729 // the hood each proxy should correctly call CloseStream() if OpenStream() | 660 // the hood each proxy should correctly call CloseStream() if OpenStream() |
| 730 // succeeded or not. | 661 // succeeded or not. |
| 731 proxy3->Stop(); | |
| 732 proxy3->Close(); | |
| 733 proxy2->Stop(); | 662 proxy2->Stop(); |
| 734 proxy2->Close(); | 663 CloseAndWaitForCloseTimer(proxy2, &stream2); |
| 664 |
| 735 proxy1->Stop(); | 665 proxy1->Stop(); |
| 736 proxy1->Close(); | 666 CloseAndWaitForCloseTimer(proxy1, &stream1); |
| 737 | 667 |
| 738 // Wait for all of the messages to fly and then verify stream behavior. | |
| 739 WaitForCloseTimer(kTestCloseDelayMs); | |
| 740 EXPECT_TRUE(stream1.stop_called()); | 668 EXPECT_TRUE(stream1.stop_called()); |
| 741 EXPECT_TRUE(stream1.start_called()); | 669 EXPECT_TRUE(stream1.start_called()); |
| 742 EXPECT_TRUE(stream2.stop_called()); | 670 EXPECT_TRUE(stream2.stop_called()); |
| 743 EXPECT_TRUE(stream2.start_called()); | 671 EXPECT_TRUE(stream2.start_called()); |
| 744 EXPECT_FALSE(stream3.stop_called()); | |
| 745 EXPECT_FALSE(stream3.start_called()); | |
| 746 } | 672 } |
| 747 | 673 |
| 748 } // namespace media | 674 } // namespace media |
| OLD | NEW |