OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/message_loop.h" | 5 #include "base/message_loop.h" |
6 #include "base/stringprintf.h" | 6 #include "base/stringprintf.h" |
7 #include "media/audio/linux/alsa_output.h" | 7 #include "media/audio/linux/alsa_output.h" |
8 #include "media/audio/linux/alsa_wrapper.h" | 8 #include "media/audio/linux/alsa_wrapper.h" |
9 #include "media/audio/linux/audio_manager_linux.h" | 9 #include "media/audio/linux/audio_manager_linux.h" |
10 #include "media/base/data_buffer.h" | 10 #include "media/base/data_buffer.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 AudioParameters params)); | 84 AudioParameters params)); |
85 MOCK_METHOD0(MuteAll, void()); | 85 MOCK_METHOD0(MuteAll, void()); |
86 MOCK_METHOD0(UnMuteAll, void()); | 86 MOCK_METHOD0(UnMuteAll, void()); |
87 | 87 |
88 MOCK_METHOD1(ReleaseOutputStream, void(AlsaPcmOutputStream* stream)); | 88 MOCK_METHOD1(ReleaseOutputStream, void(AlsaPcmOutputStream* stream)); |
89 }; | 89 }; |
90 | 90 |
91 class AlsaPcmOutputStreamTest : public testing::Test { | 91 class AlsaPcmOutputStreamTest : public testing::Test { |
92 protected: | 92 protected: |
93 AlsaPcmOutputStreamTest() { | 93 AlsaPcmOutputStreamTest() { |
94 test_stream_ = CreateStream(kTestChannelLayout); | 94 test_stream_.reset(CreateStream(kTestChannelLayout)); |
95 } | 95 } |
96 | 96 |
97 virtual ~AlsaPcmOutputStreamTest() { | 97 virtual ~AlsaPcmOutputStreamTest() { |
98 test_stream_ = NULL; | 98 test_stream_.reset(NULL); |
99 } | 99 } |
100 | 100 |
101 AlsaPcmOutputStream* CreateStream(ChannelLayout layout) { | 101 AlsaPcmOutputStream* CreateStream(ChannelLayout layout) { |
102 return CreateStream(layout, kTestFramesPerPacket); | 102 return CreateStream(layout, kTestFramesPerPacket); |
103 } | 103 } |
104 | 104 |
105 AlsaPcmOutputStream* CreateStream(ChannelLayout layout, | 105 AlsaPcmOutputStream* CreateStream(ChannelLayout layout, |
106 int32 samples_per_packet) { | 106 int32 samples_per_packet) { |
107 AudioParameters params(kTestFormat, layout, kTestSampleRate, | 107 AudioParameters params(kTestFormat, layout, kTestSampleRate, |
108 kTestBitsPerSample, samples_per_packet); | 108 kTestBitsPerSample, samples_per_packet); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 static char kSurround41[]; | 149 static char kSurround41[]; |
150 static char kSurround50[]; | 150 static char kSurround50[]; |
151 static char kSurround51[]; | 151 static char kSurround51[]; |
152 static char kSurround70[]; | 152 static char kSurround70[]; |
153 static char kSurround71[]; | 153 static char kSurround71[]; |
154 static void* kFakeHints[]; | 154 static void* kFakeHints[]; |
155 | 155 |
156 StrictMock<MockAlsaWrapper> mock_alsa_wrapper_; | 156 StrictMock<MockAlsaWrapper> mock_alsa_wrapper_; |
157 StrictMock<MockAudioManagerLinux> mock_manager_; | 157 StrictMock<MockAudioManagerLinux> mock_manager_; |
158 MessageLoop message_loop_; | 158 MessageLoop message_loop_; |
159 scoped_refptr<AlsaPcmOutputStream> test_stream_; | 159 scoped_ptr<AlsaPcmOutputStream> test_stream_; |
160 scoped_refptr<media::DataBuffer> packet_; | 160 scoped_refptr<media::DataBuffer> packet_; |
161 | 161 |
162 private: | 162 private: |
163 DISALLOW_COPY_AND_ASSIGN(AlsaPcmOutputStreamTest); | 163 DISALLOW_COPY_AND_ASSIGN(AlsaPcmOutputStreamTest); |
164 }; | 164 }; |
165 | 165 |
166 const ChannelLayout AlsaPcmOutputStreamTest::kTestChannelLayout = | 166 const ChannelLayout AlsaPcmOutputStreamTest::kTestChannelLayout = |
167 CHANNEL_LAYOUT_STEREO; | 167 CHANNEL_LAYOUT_STEREO; |
168 const int AlsaPcmOutputStreamTest::kTestSampleRate = | 168 const int AlsaPcmOutputStreamTest::kTestSampleRate = |
169 AudioParameters::kAudioCDSampleRate; | 169 AudioParameters::kAudioCDSampleRate; |
(...skipping 17 matching lines...) Expand all Loading... |
187 char AlsaPcmOutputStreamTest::kSurround41[] = "surround41:CARD=foo,DEV=0"; | 187 char AlsaPcmOutputStreamTest::kSurround41[] = "surround41:CARD=foo,DEV=0"; |
188 char AlsaPcmOutputStreamTest::kSurround50[] = "surround50:CARD=foo,DEV=0"; | 188 char AlsaPcmOutputStreamTest::kSurround50[] = "surround50:CARD=foo,DEV=0"; |
189 char AlsaPcmOutputStreamTest::kSurround51[] = "surround51:CARD=foo,DEV=0"; | 189 char AlsaPcmOutputStreamTest::kSurround51[] = "surround51:CARD=foo,DEV=0"; |
190 char AlsaPcmOutputStreamTest::kSurround70[] = "surround70:CARD=foo,DEV=0"; | 190 char AlsaPcmOutputStreamTest::kSurround70[] = "surround70:CARD=foo,DEV=0"; |
191 char AlsaPcmOutputStreamTest::kSurround71[] = "surround71:CARD=foo,DEV=0"; | 191 char AlsaPcmOutputStreamTest::kSurround71[] = "surround71:CARD=foo,DEV=0"; |
192 void* AlsaPcmOutputStreamTest::kFakeHints[] = { | 192 void* AlsaPcmOutputStreamTest::kFakeHints[] = { |
193 kSurround40, kSurround41, kSurround50, kSurround51, | 193 kSurround40, kSurround41, kSurround50, kSurround51, |
194 kSurround70, kSurround71, NULL }; | 194 kSurround70, kSurround71, NULL }; |
195 | 195 |
196 TEST_F(AlsaPcmOutputStreamTest, ConstructedState) { | 196 TEST_F(AlsaPcmOutputStreamTest, ConstructedState) { |
197 EXPECT_EQ(AlsaPcmOutputStream::kCreated, | 197 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream_->state()); |
198 test_stream_->shared_data_.state()); | |
199 | 198 |
200 // Should support mono. | 199 // Should support mono. |
201 test_stream_ = CreateStream(CHANNEL_LAYOUT_MONO); | 200 test_stream_.reset(CreateStream(CHANNEL_LAYOUT_MONO)); |
202 EXPECT_EQ(AlsaPcmOutputStream::kCreated, | 201 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream_->state()); |
203 test_stream_->shared_data_.state()); | |
204 | 202 |
205 // Should support multi-channel. | 203 // Should support multi-channel. |
206 test_stream_ = CreateStream(CHANNEL_LAYOUT_SURROUND); | 204 test_stream_.reset(CreateStream(CHANNEL_LAYOUT_SURROUND)); |
207 EXPECT_EQ(AlsaPcmOutputStream::kCreated, | 205 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream_->state()); |
208 test_stream_->shared_data_.state()); | |
209 | 206 |
210 // Bad bits per sample. | 207 // Bad bits per sample. |
211 AudioParameters bad_bps_params(kTestFormat, kTestChannelLayout, | 208 AudioParameters bad_bps_params(kTestFormat, kTestChannelLayout, |
212 kTestSampleRate, kTestBitsPerSample - 1, | 209 kTestSampleRate, kTestBitsPerSample - 1, |
213 kTestFramesPerPacket); | 210 kTestFramesPerPacket); |
214 test_stream_ = new AlsaPcmOutputStream(kTestDeviceName, | 211 test_stream_.reset(new AlsaPcmOutputStream(kTestDeviceName, |
215 bad_bps_params, | 212 bad_bps_params, |
216 &mock_alsa_wrapper_, | 213 &mock_alsa_wrapper_, |
217 &mock_manager_, | 214 &mock_manager_, |
218 &message_loop_); | 215 &message_loop_)); |
219 EXPECT_EQ(AlsaPcmOutputStream::kInError, | 216 EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream_->state()); |
220 test_stream_->shared_data_.state()); | |
221 | 217 |
222 // Bad format. | 218 // Bad format. |
223 AudioParameters bad_format_params( | 219 AudioParameters bad_format_params( |
224 AudioParameters::AUDIO_LAST_FORMAT, kTestChannelLayout, kTestSampleRate, | 220 AudioParameters::AUDIO_LAST_FORMAT, kTestChannelLayout, kTestSampleRate, |
225 kTestBitsPerSample, kTestFramesPerPacket); | 221 kTestBitsPerSample, kTestFramesPerPacket); |
226 test_stream_ = new AlsaPcmOutputStream(kTestDeviceName, | 222 test_stream_.reset(new AlsaPcmOutputStream(kTestDeviceName, |
227 bad_format_params, | 223 bad_format_params, |
228 &mock_alsa_wrapper_, | 224 &mock_alsa_wrapper_, |
229 &mock_manager_, | 225 &mock_manager_, |
230 &message_loop_); | 226 &message_loop_)); |
231 EXPECT_EQ(AlsaPcmOutputStream::kInError, | 227 EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream_->state()); |
232 test_stream_->shared_data_.state()); | |
233 } | 228 } |
234 | 229 |
235 TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) { | 230 TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) { |
236 const double kMicrosPerFrame = | 231 const double kMicrosPerFrame = |
237 static_cast<double>(1000000) / kTestSampleRate; | 232 static_cast<double>(1000000) / kTestSampleRate; |
238 const double kPacketFramesInMinLatency = | 233 const double kPacketFramesInMinLatency = |
239 AlsaPcmOutputStream::kMinLatencyMicros / kMicrosPerFrame / 2.0; | 234 AlsaPcmOutputStream::kMinLatencyMicros / kMicrosPerFrame / 2.0; |
240 | 235 |
241 // Test that packets which would cause a latency under less than | 236 // Test that packets which would cause a latency under less than |
242 // AlsaPcmOutputStream::kMinLatencyMicros will get clipped to | 237 // AlsaPcmOutputStream::kMinLatencyMicros will get clipped to |
243 // AlsaPcmOutputStream::kMinLatencyMicros, | 238 // AlsaPcmOutputStream::kMinLatencyMicros, |
244 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 239 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
245 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), | 240 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), |
246 Return(0))); | 241 Return(0))); |
247 EXPECT_CALL(mock_alsa_wrapper_, | 242 EXPECT_CALL(mock_alsa_wrapper_, |
248 PcmSetParams(_, _, _, _, _, _, | 243 PcmSetParams(_, _, _, _, _, _, |
249 AlsaPcmOutputStream::kMinLatencyMicros)) | 244 AlsaPcmOutputStream::kMinLatencyMicros)) |
250 .WillOnce(Return(0)); | 245 .WillOnce(Return(0)); |
251 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) | 246 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) |
252 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), | 247 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), |
253 SetArgumentPointee<2>(kTestFramesPerPacket / 2), | 248 SetArgumentPointee<2>(kTestFramesPerPacket / 2), |
254 Return(0))); | 249 Return(0))); |
255 | 250 |
256 test_stream_ = CreateStream(kTestChannelLayout, kPacketFramesInMinLatency); | 251 test_stream_.reset(CreateStream(kTestChannelLayout, |
| 252 kPacketFramesInMinLatency)); |
257 ASSERT_TRUE(test_stream_->Open()); | 253 ASSERT_TRUE(test_stream_->Open()); |
258 message_loop_.RunAllPending(); | 254 message_loop_.RunAllPending(); |
259 | 255 |
260 // Now close it and test that everything was released. | 256 // Now close it and test that everything was released. |
261 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)).WillOnce(Return(0)); | 257 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)).WillOnce(Return(0)); |
262 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 258 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
263 .WillOnce(Return(kTestDeviceName)); | 259 .WillOnce(Return(kTestDeviceName)); |
264 EXPECT_CALL(mock_manager_, ReleaseOutputStream(test_stream_.get())); | 260 EXPECT_CALL(mock_manager_, ReleaseOutputStream(test_stream_.get())); |
265 test_stream_->Close(); | 261 test_stream_->Close(); |
266 message_loop_.RunAllPending(); | 262 message_loop_.RunAllPending(); |
267 | 263 |
268 Mock::VerifyAndClear(&mock_alsa_wrapper_); | 264 Mock::VerifyAndClear(&mock_alsa_wrapper_); |
269 Mock::VerifyAndClear(&mock_manager_); | 265 Mock::VerifyAndClear(&mock_manager_); |
270 | 266 |
271 // Test that having more packets ends up with a latency based on packet size. | 267 // Test that having more packets ends up with a latency based on packet size. |
272 const int kOverMinLatencyPacketSize = kPacketFramesInMinLatency + 1; | 268 const int kOverMinLatencyPacketSize = kPacketFramesInMinLatency + 1; |
273 int64 expected_micros = 2 * AlsaPcmOutputStream::FramesToMicros( | 269 int64 expected_micros = 2 * AlsaPcmOutputStream::FramesToMicros( |
274 kOverMinLatencyPacketSize, kTestSampleRate); | 270 kOverMinLatencyPacketSize, kTestSampleRate); |
275 | 271 |
276 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 272 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
277 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); | 273 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); |
278 EXPECT_CALL(mock_alsa_wrapper_, | 274 EXPECT_CALL(mock_alsa_wrapper_, |
279 PcmSetParams(_, _, _, _, _, _, expected_micros)) | 275 PcmSetParams(_, _, _, _, _, _, expected_micros)) |
280 .WillOnce(Return(0)); | 276 .WillOnce(Return(0)); |
281 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) | 277 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) |
282 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), | 278 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), |
283 SetArgumentPointee<2>(kTestFramesPerPacket / 2), | 279 SetArgumentPointee<2>(kTestFramesPerPacket / 2), |
284 Return(0))); | 280 Return(0))); |
285 | 281 |
286 test_stream_ = CreateStream(kTestChannelLayout, kOverMinLatencyPacketSize); | 282 test_stream_.reset(CreateStream(kTestChannelLayout, |
| 283 kOverMinLatencyPacketSize)); |
287 ASSERT_TRUE(test_stream_->Open()); | 284 ASSERT_TRUE(test_stream_->Open()); |
288 message_loop_.RunAllPending(); | 285 message_loop_.RunAllPending(); |
289 | 286 |
290 // Now close it and test that everything was released. | 287 // Now close it and test that everything was released. |
291 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) | 288 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) |
292 .WillOnce(Return(0)); | 289 .WillOnce(Return(0)); |
293 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 290 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
294 .WillOnce(Return(kTestDeviceName)); | 291 .WillOnce(Return(kTestDeviceName)); |
295 EXPECT_CALL(mock_manager_, ReleaseOutputStream(test_stream_.get())); | 292 EXPECT_CALL(mock_manager_, ReleaseOutputStream(test_stream_.get())); |
296 test_stream_->Close(); | 293 test_stream_->Close(); |
(...skipping 27 matching lines...) Expand all Loading... |
324 .WillOnce(Return(0)); | 321 .WillOnce(Return(0)); |
325 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(kFakeHandle, _, _)) | 322 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(kFakeHandle, _, _)) |
326 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), | 323 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), |
327 SetArgumentPointee<2>(kTestFramesPerPacket / 2), | 324 SetArgumentPointee<2>(kTestFramesPerPacket / 2), |
328 Return(0))); | 325 Return(0))); |
329 | 326 |
330 // Open the stream. | 327 // Open the stream. |
331 ASSERT_TRUE(test_stream_->Open()); | 328 ASSERT_TRUE(test_stream_->Open()); |
332 message_loop_.RunAllPending(); | 329 message_loop_.RunAllPending(); |
333 | 330 |
334 EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, | 331 EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream_->state()); |
335 test_stream_->shared_data_.state()); | |
336 EXPECT_EQ(kFakeHandle, test_stream_->playback_handle_); | 332 EXPECT_EQ(kFakeHandle, test_stream_->playback_handle_); |
337 EXPECT_EQ(kTestFramesPerPacket, test_stream_->frames_per_packet_); | 333 EXPECT_EQ(kTestFramesPerPacket, test_stream_->frames_per_packet_); |
338 EXPECT_TRUE(test_stream_->buffer_.get()); | 334 EXPECT_TRUE(test_stream_->buffer_.get()); |
339 EXPECT_FALSE(test_stream_->stop_stream_); | 335 EXPECT_FALSE(test_stream_->stop_stream_); |
340 | 336 |
341 // Now close it and test that everything was released. | 337 // Now close it and test that everything was released. |
342 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) | 338 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) |
343 .WillOnce(Return(0)); | 339 .WillOnce(Return(0)); |
344 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 340 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
345 .WillOnce(Return(kTestDeviceName)); | 341 .WillOnce(Return(kTestDeviceName)); |
346 EXPECT_CALL(mock_manager_, ReleaseOutputStream(test_stream_.get())); | 342 EXPECT_CALL(mock_manager_, ReleaseOutputStream(test_stream_.get())); |
347 test_stream_->Close(); | 343 test_stream_->Close(); |
348 message_loop_.RunAllPending(); | 344 message_loop_.RunAllPending(); |
349 | 345 |
350 EXPECT_TRUE(test_stream_->playback_handle_ == NULL); | 346 EXPECT_TRUE(test_stream_->playback_handle_ == NULL); |
351 EXPECT_FALSE(test_stream_->buffer_.get()); | 347 EXPECT_FALSE(test_stream_->buffer_.get()); |
352 EXPECT_TRUE(test_stream_->stop_stream_); | 348 EXPECT_TRUE(test_stream_->stop_stream_); |
353 } | 349 } |
354 | 350 |
355 TEST_F(AlsaPcmOutputStreamTest, PcmOpenFailed) { | 351 TEST_F(AlsaPcmOutputStreamTest, PcmOpenFailed) { |
356 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 352 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
357 .WillOnce(Return(kTestFailedErrno)); | 353 .WillOnce(Return(kTestFailedErrno)); |
358 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) | 354 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) |
359 .WillOnce(Return(kDummyMessage)); | 355 .WillOnce(Return(kDummyMessage)); |
360 | 356 |
361 // Open still succeeds since PcmOpen is delegated to another thread. | 357 // Open still succeeds since PcmOpen is delegated to another thread. |
362 ASSERT_TRUE(test_stream_->Open()); | 358 ASSERT_TRUE(test_stream_->Open()); |
363 ASSERT_EQ(AlsaPcmOutputStream::kIsOpened, | 359 ASSERT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream_->state()); |
364 test_stream_->shared_data_.state()); | |
365 ASSERT_FALSE(test_stream_->stop_stream_); | 360 ASSERT_FALSE(test_stream_->stop_stream_); |
366 message_loop_.RunAllPending(); | 361 message_loop_.RunAllPending(); |
367 | 362 |
368 // Ensure internal state is set for a no-op stream if PcmOpen() failes. | 363 // Ensure internal state is set for a no-op stream if PcmOpen() failes. |
369 EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, | 364 EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream_->state()); |
370 test_stream_->shared_data_.state()); | |
371 EXPECT_TRUE(test_stream_->stop_stream_); | 365 EXPECT_TRUE(test_stream_->stop_stream_); |
372 EXPECT_TRUE(test_stream_->playback_handle_ == NULL); | 366 EXPECT_TRUE(test_stream_->playback_handle_ == NULL); |
373 EXPECT_FALSE(test_stream_->buffer_.get()); | 367 EXPECT_FALSE(test_stream_->buffer_.get()); |
374 | 368 |
375 // Close the stream since we opened it to make destruction happy. | 369 // Close the stream since we opened it to make destruction happy. |
376 EXPECT_CALL(mock_manager_, ReleaseOutputStream(test_stream_.get())); | 370 EXPECT_CALL(mock_manager_, ReleaseOutputStream(test_stream_.get())); |
377 test_stream_->Close(); | 371 test_stream_->Close(); |
378 message_loop_.RunAllPending(); | 372 message_loop_.RunAllPending(); |
379 } | 373 } |
380 | 374 |
381 TEST_F(AlsaPcmOutputStreamTest, PcmSetParamsFailed) { | 375 TEST_F(AlsaPcmOutputStreamTest, PcmSetParamsFailed) { |
382 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 376 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
383 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), | 377 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), |
384 Return(0))); | 378 Return(0))); |
385 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) | 379 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) |
386 .WillOnce(Return(kTestFailedErrno)); | 380 .WillOnce(Return(kTestFailedErrno)); |
387 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) | 381 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) |
388 .WillOnce(Return(0)); | 382 .WillOnce(Return(0)); |
389 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 383 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
390 .WillOnce(Return(kTestDeviceName)); | 384 .WillOnce(Return(kTestDeviceName)); |
391 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) | 385 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) |
392 .WillOnce(Return(kDummyMessage)); | 386 .WillOnce(Return(kDummyMessage)); |
393 | 387 |
394 // If open fails, the stream stays in kCreated because it has effectively had | 388 // If open fails, the stream stays in kCreated because it has effectively had |
395 // no changes. | 389 // no changes. |
396 ASSERT_TRUE(test_stream_->Open()); | 390 ASSERT_TRUE(test_stream_->Open()); |
397 EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, | 391 EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream_->state()); |
398 test_stream_->shared_data_.state()); | |
399 ASSERT_FALSE(test_stream_->stop_stream_); | 392 ASSERT_FALSE(test_stream_->stop_stream_); |
400 message_loop_.RunAllPending(); | 393 message_loop_.RunAllPending(); |
401 | 394 |
402 // Ensure internal state is set for a no-op stream if PcmSetParams() failes. | 395 // Ensure internal state is set for a no-op stream if PcmSetParams() failes. |
403 EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, | 396 EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream_->state()); |
404 test_stream_->shared_data_.state()); | |
405 EXPECT_TRUE(test_stream_->stop_stream_); | 397 EXPECT_TRUE(test_stream_->stop_stream_); |
406 EXPECT_TRUE(test_stream_->playback_handle_ == NULL); | 398 EXPECT_TRUE(test_stream_->playback_handle_ == NULL); |
407 EXPECT_FALSE(test_stream_->buffer_.get()); | 399 EXPECT_FALSE(test_stream_->buffer_.get()); |
408 | 400 |
409 // Close the stream since we opened it to make destruction happy. | 401 // Close the stream since we opened it to make destruction happy. |
410 EXPECT_CALL(mock_manager_, ReleaseOutputStream(test_stream_.get())); | 402 EXPECT_CALL(mock_manager_, ReleaseOutputStream(test_stream_.get())); |
411 test_stream_->Close(); | 403 test_stream_->Close(); |
412 message_loop_.RunAllPending(); | 404 message_loop_.RunAllPending(); |
413 } | 405 } |
414 | 406 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 .WillOnce(DoAll(SetArgumentPointee<1>(1), Return(0))); | 546 .WillOnce(DoAll(SetArgumentPointee<1>(1), Return(0))); |
555 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 547 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
556 .WillRepeatedly(Return(0)); // Buffer is full. | 548 .WillRepeatedly(Return(0)); // Buffer is full. |
557 | 549 |
558 // Return a partially filled packet. | 550 // Return a partially filled packet. |
559 EXPECT_CALL(mock_callback, | 551 EXPECT_CALL(mock_callback, |
560 OnMoreData(test_stream_.get(), _, _, _)) | 552 OnMoreData(test_stream_.get(), _, _, _)) |
561 .WillOnce(Return(10)); | 553 .WillOnce(Return(10)); |
562 | 554 |
563 bool source_exhausted; | 555 bool source_exhausted; |
564 test_stream_->shared_data_.set_source_callback(&mock_callback); | 556 test_stream_->set_source_callback(&mock_callback); |
565 test_stream_->packet_size_ = kTestPacketSize; | 557 test_stream_->packet_size_ = kTestPacketSize; |
566 test_stream_->BufferPacket(&source_exhausted); | 558 test_stream_->BufferPacket(&source_exhausted); |
567 | 559 |
568 EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes()); | 560 EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes()); |
569 EXPECT_FALSE(source_exhausted); | 561 EXPECT_FALSE(source_exhausted); |
570 } | 562 } |
571 | 563 |
572 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) { | 564 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) { |
573 InitBuffer(); | 565 InitBuffer(); |
574 test_stream_->buffer_->Clear(); | 566 test_stream_->buffer_->Clear(); |
575 | 567 |
576 // Simulate where the underrun has occurred right after checking the delay. | 568 // Simulate where the underrun has occurred right after checking the delay. |
577 MockAudioSourceCallback mock_callback; | 569 MockAudioSourceCallback mock_callback; |
578 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 570 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
579 .WillOnce(Return(SND_PCM_STATE_RUNNING)); | 571 .WillOnce(Return(SND_PCM_STATE_RUNNING)); |
580 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) | 572 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) |
581 .WillOnce(DoAll(SetArgumentPointee<1>(-1), Return(0))); | 573 .WillOnce(DoAll(SetArgumentPointee<1>(-1), Return(0))); |
582 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 574 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
583 .WillRepeatedly(Return(0)); // Buffer is full. | 575 .WillRepeatedly(Return(0)); // Buffer is full. |
584 EXPECT_CALL(mock_callback, | 576 EXPECT_CALL(mock_callback, |
585 OnMoreData(test_stream_.get(), _, _, _)) | 577 OnMoreData(test_stream_.get(), _, _, _)) |
586 .WillOnce(Return(10)); | 578 .WillOnce(Return(10)); |
587 | 579 |
588 bool source_exhausted; | 580 bool source_exhausted; |
589 test_stream_->shared_data_.set_source_callback(&mock_callback); | 581 test_stream_->set_source_callback(&mock_callback); |
590 test_stream_->packet_size_ = kTestPacketSize; | 582 test_stream_->packet_size_ = kTestPacketSize; |
591 test_stream_->BufferPacket(&source_exhausted); | 583 test_stream_->BufferPacket(&source_exhausted); |
592 | 584 |
593 EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes()); | 585 EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes()); |
594 EXPECT_FALSE(source_exhausted); | 586 EXPECT_FALSE(source_exhausted); |
595 } | 587 } |
596 | 588 |
597 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) { | 589 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) { |
598 InitBuffer(); | 590 InitBuffer(); |
599 test_stream_->buffer_->Clear(); | 591 test_stream_->buffer_->Clear(); |
600 | 592 |
601 // If ALSA has underrun then we should assume a delay of zero. | 593 // If ALSA has underrun then we should assume a delay of zero. |
602 MockAudioSourceCallback mock_callback; | 594 MockAudioSourceCallback mock_callback; |
603 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 595 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
604 .WillOnce(Return(SND_PCM_STATE_XRUN)); | 596 .WillOnce(Return(SND_PCM_STATE_XRUN)); |
605 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 597 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
606 .WillRepeatedly(Return(0)); // Buffer is full. | 598 .WillRepeatedly(Return(0)); // Buffer is full. |
607 EXPECT_CALL(mock_callback, | 599 EXPECT_CALL(mock_callback, |
608 OnMoreData(test_stream_.get(), _, _, AllOf( | 600 OnMoreData(test_stream_.get(), _, _, AllOf( |
609 Field(&AudioBuffersState::pending_bytes, 0), | 601 Field(&AudioBuffersState::pending_bytes, 0), |
610 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) | 602 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) |
611 .WillOnce(Return(10)); | 603 .WillOnce(Return(10)); |
612 | 604 |
613 bool source_exhausted; | 605 bool source_exhausted; |
614 test_stream_->shared_data_.set_source_callback(&mock_callback); | 606 test_stream_->set_source_callback(&mock_callback); |
615 test_stream_->packet_size_ = kTestPacketSize; | 607 test_stream_->packet_size_ = kTestPacketSize; |
616 test_stream_->BufferPacket(&source_exhausted); | 608 test_stream_->BufferPacket(&source_exhausted); |
617 | 609 |
618 EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes()); | 610 EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes()); |
619 EXPECT_FALSE(source_exhausted); | 611 EXPECT_FALSE(source_exhausted); |
620 } | 612 } |
621 | 613 |
622 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_FullBuffer) { | 614 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_FullBuffer) { |
623 InitBuffer(); | 615 InitBuffer(); |
624 // No expectations set on the strict mock because nothing should be called. | 616 // No expectations set on the strict mock because nothing should be called. |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 PcmSetParams(kFakeHandle, _, _, i, _, _, _)) | 673 PcmSetParams(kFakeHandle, _, _, i, _, _, _)) |
682 .WillOnce(Return(0)); | 674 .WillOnce(Return(0)); |
683 | 675 |
684 // The parameters are specified by ALSA documentation, and are in constants | 676 // The parameters are specified by ALSA documentation, and are in constants |
685 // in the implementation files. | 677 // in the implementation files. |
686 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("IOID"))) | 678 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("IOID"))) |
687 .WillRepeatedly(Invoke(OutputHint)); | 679 .WillRepeatedly(Invoke(OutputHint)); |
688 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("NAME"))) | 680 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("NAME"))) |
689 .WillRepeatedly(Invoke(EchoHint)); | 681 .WillRepeatedly(Invoke(EchoHint)); |
690 | 682 |
691 test_stream_ = CreateStream(kExpectedLayouts[i]); | 683 test_stream_.reset(CreateStream(kExpectedLayouts[i])); |
692 EXPECT_TRUE(test_stream_->AutoSelectDevice(i)); | 684 EXPECT_TRUE(test_stream_->AutoSelectDevice(i)); |
693 EXPECT_EQ(kExpectedDownmix[i], test_stream_->should_downmix_); | 685 EXPECT_EQ(kExpectedDownmix[i], test_stream_->should_downmix_); |
694 | 686 |
695 Mock::VerifyAndClearExpectations(&mock_alsa_wrapper_); | 687 Mock::VerifyAndClearExpectations(&mock_alsa_wrapper_); |
696 Mock::VerifyAndClearExpectations(&mock_manager_); | 688 Mock::VerifyAndClearExpectations(&mock_manager_); |
697 } | 689 } |
698 } | 690 } |
699 | 691 |
700 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_FallbackDevices) { | 692 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_FallbackDevices) { |
701 using std::string; | 693 using std::string; |
(...skipping 29 matching lines...) Expand all Loading... |
731 InSequence s; | 723 InSequence s; |
732 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(first_try.c_str()), _, _)) | 724 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(first_try.c_str()), _, _)) |
733 .WillOnce(Return(kTestFailedErrno)); | 725 .WillOnce(Return(kTestFailedErrno)); |
734 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(second_try.c_str()), _, _)) | 726 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(second_try.c_str()), _, _)) |
735 .WillOnce(Return(kTestFailedErrno)); | 727 .WillOnce(Return(kTestFailedErrno)); |
736 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(third_try.c_str()), _, _)) | 728 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(third_try.c_str()), _, _)) |
737 .WillOnce(Return(kTestFailedErrno)); | 729 .WillOnce(Return(kTestFailedErrno)); |
738 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(fourth_try.c_str()), _, _)) | 730 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(fourth_try.c_str()), _, _)) |
739 .WillOnce(Return(kTestFailedErrno)); | 731 .WillOnce(Return(kTestFailedErrno)); |
740 | 732 |
741 test_stream_ = CreateStream(CHANNEL_LAYOUT_5POINT0); | 733 test_stream_.reset(CreateStream(CHANNEL_LAYOUT_5POINT0)); |
742 EXPECT_FALSE(test_stream_->AutoSelectDevice(5)); | 734 EXPECT_FALSE(test_stream_->AutoSelectDevice(5)); |
743 } | 735 } |
744 | 736 |
745 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_HintFail) { | 737 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_HintFail) { |
746 // Should get |kDefaultDevice|, and force a 2-channel downmix on a failure to | 738 // Should get |kDefaultDevice|, and force a 2-channel downmix on a failure to |
747 // enumerate devices. | 739 // enumerate devices. |
748 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameHint(_, _, _)) | 740 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameHint(_, _, _)) |
749 .WillRepeatedly(Return(kTestFailedErrno)); | 741 .WillRepeatedly(Return(kTestFailedErrno)); |
750 EXPECT_CALL(mock_alsa_wrapper_, | 742 EXPECT_CALL(mock_alsa_wrapper_, |
751 PcmOpen(_, StrEq(AlsaPcmOutputStream::kDefaultDevice), _, _)) | 743 PcmOpen(_, StrEq(AlsaPcmOutputStream::kDefaultDevice), _, _)) |
752 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); | 744 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); |
753 EXPECT_CALL(mock_alsa_wrapper_, | 745 EXPECT_CALL(mock_alsa_wrapper_, |
754 PcmSetParams(kFakeHandle, _, _, 2, _, _, _)) | 746 PcmSetParams(kFakeHandle, _, _, 2, _, _, _)) |
755 .WillOnce(Return(0)); | 747 .WillOnce(Return(0)); |
756 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) | 748 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) |
757 .WillOnce(Return(kDummyMessage)); | 749 .WillOnce(Return(kDummyMessage)); |
758 | 750 |
759 test_stream_ = CreateStream(CHANNEL_LAYOUT_5POINT0); | 751 test_stream_.reset(CreateStream(CHANNEL_LAYOUT_5POINT0)); |
760 EXPECT_TRUE(test_stream_->AutoSelectDevice(5)); | 752 EXPECT_TRUE(test_stream_->AutoSelectDevice(5)); |
761 EXPECT_TRUE(test_stream_->should_downmix_); | 753 EXPECT_TRUE(test_stream_->should_downmix_); |
762 } | 754 } |
763 | 755 |
764 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_StopStream) { | 756 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_StopStream) { |
765 InitBuffer(); | 757 InitBuffer(); |
766 test_stream_->stop_stream_ = true; | 758 test_stream_->stop_stream_ = true; |
767 bool source_exhausted; | 759 bool source_exhausted; |
768 test_stream_->BufferPacket(&source_exhausted); | 760 test_stream_->BufferPacket(&source_exhausted); |
769 EXPECT_EQ(0u, test_stream_->buffer_->forward_bytes()); | 761 EXPECT_EQ(0u, test_stream_->buffer_->forward_bytes()); |
770 EXPECT_TRUE(source_exhausted); | 762 EXPECT_TRUE(source_exhausted); |
771 } | 763 } |
772 | 764 |
773 TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite) { | 765 TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite) { |
774 test_stream_->shared_data_.TransitionTo(AlsaPcmOutputStream::kIsOpened); | 766 test_stream_->TransitionTo(AlsaPcmOutputStream::kIsOpened); |
775 test_stream_->shared_data_.TransitionTo(AlsaPcmOutputStream::kIsPlaying); | 767 test_stream_->TransitionTo(AlsaPcmOutputStream::kIsPlaying); |
776 | 768 |
777 InitBuffer(); | 769 InitBuffer(); |
778 | 770 |
779 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 771 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
780 .WillOnce(Return(10)); | 772 .WillOnce(Return(10)); |
781 test_stream_->ScheduleNextWrite(false); | 773 test_stream_->ScheduleNextWrite(false); |
782 | 774 |
783 // TODO(sergeyu): Figure out how to check that the task has been added to the | 775 // TODO(sergeyu): Figure out how to check that the task has been added to the |
784 // message loop. | 776 // message loop. |
785 | 777 |
786 // Cleanup the message queue. Currently ~MessageQueue() doesn't free pending | 778 // Cleanup the message queue. Currently ~MessageQueue() doesn't free pending |
787 // tasks unless running on valgrind. The code below is needed to keep | 779 // tasks unless running on valgrind. The code below is needed to keep |
788 // heapcheck happy. | 780 // heapcheck happy. |
789 test_stream_->stop_stream_ = true; | 781 test_stream_->stop_stream_ = true; |
790 message_loop_.RunAllPending(); | 782 message_loop_.RunAllPending(); |
791 | 783 |
792 test_stream_->shared_data_.TransitionTo(AlsaPcmOutputStream::kIsClosed); | 784 test_stream_->TransitionTo(AlsaPcmOutputStream::kIsClosed); |
793 } | 785 } |
794 | 786 |
795 TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite_StopStream) { | 787 TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite_StopStream) { |
796 test_stream_->shared_data_.TransitionTo(AlsaPcmOutputStream::kIsOpened); | 788 test_stream_->TransitionTo(AlsaPcmOutputStream::kIsOpened); |
797 test_stream_->shared_data_.TransitionTo(AlsaPcmOutputStream::kIsPlaying); | 789 test_stream_->TransitionTo(AlsaPcmOutputStream::kIsPlaying); |
798 | 790 |
799 InitBuffer(); | 791 InitBuffer(); |
800 | 792 |
801 test_stream_->stop_stream_ = true; | 793 test_stream_->stop_stream_ = true; |
802 test_stream_->ScheduleNextWrite(true); | 794 test_stream_->ScheduleNextWrite(true); |
803 | 795 |
804 // TODO(ajwong): Find a way to test whether or not another task has been | 796 // TODO(ajwong): Find a way to test whether or not another task has been |
805 // posted so we can verify that the Alsa code will indeed break the task | 797 // posted so we can verify that the Alsa code will indeed break the task |
806 // posting loop. | 798 // posting loop. |
807 | 799 |
808 test_stream_->shared_data_.TransitionTo(AlsaPcmOutputStream::kIsClosed); | 800 test_stream_->TransitionTo(AlsaPcmOutputStream::kIsClosed); |
809 } | 801 } |
OLD | NEW |