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 "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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 uint8* dest, uint32 max_size, | 71 uint8* dest, uint32 max_size, |
72 AudioBuffersState buffers_state)); | 72 AudioBuffersState buffers_state)); |
73 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); | 73 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); |
74 }; | 74 }; |
75 | 75 |
76 class MockAudioManagerLinux : public AudioManagerLinux { | 76 class MockAudioManagerLinux : public AudioManagerLinux { |
77 public: | 77 public: |
78 MOCK_METHOD0(Init, void()); | 78 MOCK_METHOD0(Init, void()); |
79 MOCK_METHOD0(HasAudioOutputDevices, bool()); | 79 MOCK_METHOD0(HasAudioOutputDevices, bool()); |
80 MOCK_METHOD0(HasAudioInputDevices, bool()); | 80 MOCK_METHOD0(HasAudioInputDevices, bool()); |
81 MOCK_METHOD1(MakeAudioOutputStream, AudioOutputStream*( | |
82 const AudioParameters& params)); | |
83 MOCK_METHOD2(MakeAudioInputStream, AudioInputStream*( | |
84 const AudioParameters& params, const std::string& device_id)); | |
85 MOCK_METHOD0(MuteAll, void()); | 81 MOCK_METHOD0(MuteAll, void()); |
86 MOCK_METHOD0(UnMuteAll, void()); | 82 MOCK_METHOD0(UnMuteAll, void()); |
87 MOCK_METHOD1(ReleaseOutputStream, void(AudioOutputStream* stream)); | 83 MOCK_METHOD1(MakeLinearOutputStream, AudioOutputStream*( |
| 84 const AudioParameters& params)); |
| 85 MOCK_METHOD1(MakeLowLatencyOutputStream, AudioOutputStream*( |
| 86 const AudioParameters& params)); |
| 87 MOCK_METHOD2(MakeLinearOutputStream, AudioInputStream*( |
| 88 const AudioParameters& params, const std::string& device_id)); |
| 89 MOCK_METHOD2(MakeLowLatencyInputStream, AudioInputStream*( |
| 90 const AudioParameters& params, const std::string& device_id)); |
| 91 |
| 92 // We need to override this function in order to skip the checking the number |
| 93 // of active output streams. It is because the number of active streams |
| 94 // is managed inside MakeAudioOutputStream, and we don't use |
| 95 // MakeAudioOutputStream to create the stream in the tests. |
| 96 virtual void ReleaseOutputStream(AudioOutputStream* stream) OVERRIDE { |
| 97 DCHECK(stream); |
| 98 delete stream; |
| 99 } |
88 | 100 |
89 // We don't mock this method since all tests will do the same thing | 101 // We don't mock this method since all tests will do the same thing |
90 // and use the current message loop. | 102 // and use the current message loop. |
91 virtual scoped_refptr<base::MessageLoopProxy> GetMessageLoop() OVERRIDE { | 103 virtual scoped_refptr<base::MessageLoopProxy> GetMessageLoop() OVERRIDE { |
92 return MessageLoop::current()->message_loop_proxy(); | 104 return MessageLoop::current()->message_loop_proxy(); |
93 } | 105 } |
94 }; | 106 }; |
95 | 107 |
96 class AlsaPcmOutputStreamTest : public testing::Test { | 108 class AlsaPcmOutputStreamTest : public testing::Test { |
97 protected: | 109 protected: |
98 AlsaPcmOutputStreamTest() { | 110 AlsaPcmOutputStreamTest() { |
99 mock_manager_.reset(new StrictMock<MockAudioManagerLinux>()); | 111 mock_manager_.reset(new StrictMock<MockAudioManagerLinux>()); |
100 test_stream_.reset(CreateStream(kTestChannelLayout)); | |
101 } | 112 } |
102 | 113 |
103 virtual ~AlsaPcmOutputStreamTest() { | 114 virtual ~AlsaPcmOutputStreamTest() { |
104 test_stream_.reset(NULL); | |
105 } | 115 } |
106 | 116 |
107 AlsaPcmOutputStream* CreateStream(ChannelLayout layout) { | 117 AlsaPcmOutputStream* CreateStream(ChannelLayout layout) { |
108 return CreateStream(layout, kTestFramesPerPacket); | 118 return CreateStream(layout, kTestFramesPerPacket); |
109 } | 119 } |
110 | 120 |
111 AlsaPcmOutputStream* CreateStream(ChannelLayout layout, | 121 AlsaPcmOutputStream* CreateStream(ChannelLayout layout, |
112 int32 samples_per_packet) { | 122 int32 samples_per_packet) { |
113 AudioParameters params(kTestFormat, layout, kTestSampleRate, | 123 AudioParameters params(kTestFormat, layout, kTestSampleRate, |
114 kTestBitsPerSample, samples_per_packet); | 124 kTestBitsPerSample, samples_per_packet); |
115 return new AlsaPcmOutputStream(kTestDeviceName, | 125 return new AlsaPcmOutputStream(kTestDeviceName, |
116 params, | 126 params, |
117 &mock_alsa_wrapper_, | 127 &mock_alsa_wrapper_, |
118 mock_manager_.get()); | 128 mock_manager_.get()); |
119 } | 129 } |
120 | 130 |
121 // Helper function to malloc the string returned by DeviceNameHint for NAME. | 131 // Helper function to malloc the string returned by DeviceNameHint for NAME. |
122 static char* EchoHint(const void* name, Unused) { | 132 static char* EchoHint(const void* name, Unused) { |
123 return strdup(static_cast<const char*>(name)); | 133 return strdup(static_cast<const char*>(name)); |
124 } | 134 } |
125 | 135 |
126 // Helper function to malloc the string returned by DeviceNameHint for IOID. | 136 // Helper function to malloc the string returned by DeviceNameHint for IOID. |
127 static char* OutputHint(Unused, Unused) { | 137 static char* OutputHint(Unused, Unused) { |
128 return strdup("Output"); | 138 return strdup("Output"); |
129 } | 139 } |
130 | 140 |
131 // Helper function to initialize |test_stream_->buffer_|. Must be called | 141 // Helper function to initialize |test_stream->buffer_|. Must be called |
132 // in all tests that use buffer_ without opening the stream. | 142 // in all tests that use buffer_ without opening the stream. |
133 void InitBuffer() { | 143 void InitBuffer(AlsaPcmOutputStream* test_stream) { |
| 144 DCHECK(test_stream); |
134 packet_ = new media::DataBuffer(kTestPacketSize); | 145 packet_ = new media::DataBuffer(kTestPacketSize); |
135 packet_->SetDataSize(kTestPacketSize); | 146 packet_->SetDataSize(kTestPacketSize); |
136 test_stream_->buffer_.reset(new media::SeekableBuffer(0, kTestPacketSize)); | 147 test_stream->buffer_.reset(new media::SeekableBuffer(0, kTestPacketSize)); |
137 test_stream_->buffer_->Append(packet_.get()); | 148 test_stream->buffer_->Append(packet_.get()); |
138 } | 149 } |
139 | 150 |
140 MockAudioManagerLinux& mock_manager() { | 151 MockAudioManagerLinux& mock_manager() { |
141 return *(mock_manager_.get()); | 152 return *(mock_manager_.get()); |
142 } | 153 } |
143 | 154 |
144 static const ChannelLayout kTestChannelLayout; | 155 static const ChannelLayout kTestChannelLayout; |
145 static const int kTestSampleRate; | 156 static const int kTestSampleRate; |
146 static const int kTestBitsPerSample; | 157 static const int kTestBitsPerSample; |
147 static const int kTestBytesPerFrame; | 158 static const int kTestBytesPerFrame; |
(...skipping 10 matching lines...) Expand all Loading... |
158 static char kSurround41[]; | 169 static char kSurround41[]; |
159 static char kSurround50[]; | 170 static char kSurround50[]; |
160 static char kSurround51[]; | 171 static char kSurround51[]; |
161 static char kSurround70[]; | 172 static char kSurround70[]; |
162 static char kSurround71[]; | 173 static char kSurround71[]; |
163 static void* kFakeHints[]; | 174 static void* kFakeHints[]; |
164 | 175 |
165 StrictMock<MockAlsaWrapper> mock_alsa_wrapper_; | 176 StrictMock<MockAlsaWrapper> mock_alsa_wrapper_; |
166 scoped_ptr<StrictMock<MockAudioManagerLinux> > mock_manager_; | 177 scoped_ptr<StrictMock<MockAudioManagerLinux> > mock_manager_; |
167 MessageLoop message_loop_; | 178 MessageLoop message_loop_; |
168 scoped_ptr<AlsaPcmOutputStream> test_stream_; | |
169 scoped_refptr<media::DataBuffer> packet_; | 179 scoped_refptr<media::DataBuffer> packet_; |
170 | 180 |
171 private: | 181 private: |
172 DISALLOW_COPY_AND_ASSIGN(AlsaPcmOutputStreamTest); | 182 DISALLOW_COPY_AND_ASSIGN(AlsaPcmOutputStreamTest); |
173 }; | 183 }; |
174 | 184 |
175 const ChannelLayout AlsaPcmOutputStreamTest::kTestChannelLayout = | 185 const ChannelLayout AlsaPcmOutputStreamTest::kTestChannelLayout = |
176 CHANNEL_LAYOUT_STEREO; | 186 CHANNEL_LAYOUT_STEREO; |
177 const int AlsaPcmOutputStreamTest::kTestSampleRate = | 187 const int AlsaPcmOutputStreamTest::kTestSampleRate = |
178 AudioParameters::kAudioCDSampleRate; | 188 AudioParameters::kAudioCDSampleRate; |
(...skipping 17 matching lines...) Expand all Loading... |
196 char AlsaPcmOutputStreamTest::kSurround41[] = "surround41:CARD=foo,DEV=0"; | 206 char AlsaPcmOutputStreamTest::kSurround41[] = "surround41:CARD=foo,DEV=0"; |
197 char AlsaPcmOutputStreamTest::kSurround50[] = "surround50:CARD=foo,DEV=0"; | 207 char AlsaPcmOutputStreamTest::kSurround50[] = "surround50:CARD=foo,DEV=0"; |
198 char AlsaPcmOutputStreamTest::kSurround51[] = "surround51:CARD=foo,DEV=0"; | 208 char AlsaPcmOutputStreamTest::kSurround51[] = "surround51:CARD=foo,DEV=0"; |
199 char AlsaPcmOutputStreamTest::kSurround70[] = "surround70:CARD=foo,DEV=0"; | 209 char AlsaPcmOutputStreamTest::kSurround70[] = "surround70:CARD=foo,DEV=0"; |
200 char AlsaPcmOutputStreamTest::kSurround71[] = "surround71:CARD=foo,DEV=0"; | 210 char AlsaPcmOutputStreamTest::kSurround71[] = "surround71:CARD=foo,DEV=0"; |
201 void* AlsaPcmOutputStreamTest::kFakeHints[] = { | 211 void* AlsaPcmOutputStreamTest::kFakeHints[] = { |
202 kSurround40, kSurround41, kSurround50, kSurround51, | 212 kSurround40, kSurround41, kSurround50, kSurround51, |
203 kSurround70, kSurround71, NULL }; | 213 kSurround70, kSurround71, NULL }; |
204 | 214 |
205 TEST_F(AlsaPcmOutputStreamTest, ConstructedState) { | 215 TEST_F(AlsaPcmOutputStreamTest, ConstructedState) { |
206 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream_->state()); | 216 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 217 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream->state()); |
| 218 test_stream->Close(); |
207 | 219 |
208 // Should support mono. | 220 // Should support mono. |
209 test_stream_.reset(CreateStream(CHANNEL_LAYOUT_MONO)); | 221 test_stream = CreateStream(CHANNEL_LAYOUT_MONO); |
210 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream_->state()); | 222 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream->state()); |
| 223 test_stream->Close(); |
211 | 224 |
212 // Should support multi-channel. | 225 // Should support multi-channel. |
213 test_stream_.reset(CreateStream(CHANNEL_LAYOUT_SURROUND)); | 226 test_stream = CreateStream(CHANNEL_LAYOUT_SURROUND); |
214 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream_->state()); | 227 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream->state()); |
| 228 test_stream->Close(); |
215 | 229 |
216 // Bad bits per sample. | 230 // Bad bits per sample. |
217 AudioParameters bad_bps_params(kTestFormat, kTestChannelLayout, | 231 AudioParameters bad_bps_params(kTestFormat, kTestChannelLayout, |
218 kTestSampleRate, kTestBitsPerSample - 1, | 232 kTestSampleRate, kTestBitsPerSample - 1, |
219 kTestFramesPerPacket); | 233 kTestFramesPerPacket); |
220 test_stream_.reset(new AlsaPcmOutputStream(kTestDeviceName, | 234 test_stream = new AlsaPcmOutputStream(kTestDeviceName, |
221 bad_bps_params, | 235 bad_bps_params, |
222 &mock_alsa_wrapper_, | 236 &mock_alsa_wrapper_, |
223 mock_manager_.get())); | 237 mock_manager_.get()); |
224 EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream_->state()); | 238 EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream->state()); |
| 239 test_stream->Close(); |
225 | 240 |
226 // Bad format. | 241 // Bad format. |
227 AudioParameters bad_format_params( | 242 AudioParameters bad_format_params( |
228 AudioParameters::AUDIO_LAST_FORMAT, kTestChannelLayout, kTestSampleRate, | 243 AudioParameters::AUDIO_LAST_FORMAT, kTestChannelLayout, kTestSampleRate, |
229 kTestBitsPerSample, kTestFramesPerPacket); | 244 kTestBitsPerSample, kTestFramesPerPacket); |
230 test_stream_.reset(new AlsaPcmOutputStream(kTestDeviceName, | 245 test_stream = new AlsaPcmOutputStream(kTestDeviceName, |
231 bad_format_params, | 246 bad_format_params, |
232 &mock_alsa_wrapper_, | 247 &mock_alsa_wrapper_, |
233 mock_manager_.get())); | 248 mock_manager_.get()); |
234 EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream_->state()); | 249 EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream->state()); |
| 250 test_stream->Close(); |
235 } | 251 } |
236 | 252 |
237 TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) { | 253 TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) { |
238 const double kMicrosPerFrame = | 254 const double kMicrosPerFrame = |
239 static_cast<double>(1000000) / kTestSampleRate; | 255 static_cast<double>(1000000) / kTestSampleRate; |
240 const double kPacketFramesInMinLatency = | 256 const double kPacketFramesInMinLatency = |
241 AlsaPcmOutputStream::kMinLatencyMicros / kMicrosPerFrame / 2.0; | 257 AlsaPcmOutputStream::kMinLatencyMicros / kMicrosPerFrame / 2.0; |
242 | 258 |
243 // Test that packets which would cause a latency under less than | 259 // Test that packets which would cause a latency under less than |
244 // AlsaPcmOutputStream::kMinLatencyMicros will get clipped to | 260 // AlsaPcmOutputStream::kMinLatencyMicros will get clipped to |
245 // AlsaPcmOutputStream::kMinLatencyMicros, | 261 // AlsaPcmOutputStream::kMinLatencyMicros, |
246 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 262 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
247 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), | 263 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), |
248 Return(0))); | 264 Return(0))); |
249 EXPECT_CALL(mock_alsa_wrapper_, | 265 EXPECT_CALL(mock_alsa_wrapper_, |
250 PcmSetParams(_, _, _, _, _, _, | 266 PcmSetParams(_, _, _, _, _, _, |
251 AlsaPcmOutputStream::kMinLatencyMicros)) | 267 AlsaPcmOutputStream::kMinLatencyMicros)) |
252 .WillOnce(Return(0)); | 268 .WillOnce(Return(0)); |
253 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) | 269 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) |
254 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), | 270 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), |
255 SetArgumentPointee<2>(kTestFramesPerPacket / 2), | 271 SetArgumentPointee<2>(kTestFramesPerPacket / 2), |
256 Return(0))); | 272 Return(0))); |
257 | 273 |
258 test_stream_.reset(CreateStream(kTestChannelLayout, | 274 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout, |
259 kPacketFramesInMinLatency)); | 275 kPacketFramesInMinLatency); |
260 ASSERT_TRUE(test_stream_->Open()); | 276 ASSERT_TRUE(test_stream->Open()); |
261 | 277 |
262 // Now close it and test that everything was released. | 278 // Now close it and test that everything was released. |
263 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)).WillOnce(Return(0)); | 279 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)).WillOnce(Return(0)); |
264 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 280 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
265 .WillOnce(Return(kTestDeviceName)); | 281 .WillOnce(Return(kTestDeviceName)); |
266 EXPECT_CALL(mock_manager(), ReleaseOutputStream(test_stream_.get())); | 282 test_stream->Close(); |
267 test_stream_->Close(); | |
268 | 283 |
269 Mock::VerifyAndClear(&mock_alsa_wrapper_); | 284 Mock::VerifyAndClear(&mock_alsa_wrapper_); |
270 Mock::VerifyAndClear(mock_manager_.get()); | 285 Mock::VerifyAndClear(mock_manager_.get()); |
271 | 286 |
272 // Test that having more packets ends up with a latency based on packet size. | 287 // Test that having more packets ends up with a latency based on packet size. |
273 const int kOverMinLatencyPacketSize = kPacketFramesInMinLatency + 1; | 288 const int kOverMinLatencyPacketSize = kPacketFramesInMinLatency + 1; |
274 int64 expected_micros = 2 * AlsaPcmOutputStream::FramesToMicros( | 289 int64 expected_micros = 2 * AlsaPcmOutputStream::FramesToMicros( |
275 kOverMinLatencyPacketSize, kTestSampleRate); | 290 kOverMinLatencyPacketSize, kTestSampleRate); |
276 | 291 |
277 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 292 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
278 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); | 293 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); |
279 EXPECT_CALL(mock_alsa_wrapper_, | 294 EXPECT_CALL(mock_alsa_wrapper_, |
280 PcmSetParams(_, _, _, _, _, _, expected_micros)) | 295 PcmSetParams(_, _, _, _, _, _, expected_micros)) |
281 .WillOnce(Return(0)); | 296 .WillOnce(Return(0)); |
282 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) | 297 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) |
283 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), | 298 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), |
284 SetArgumentPointee<2>(kTestFramesPerPacket / 2), | 299 SetArgumentPointee<2>(kTestFramesPerPacket / 2), |
285 Return(0))); | 300 Return(0))); |
286 | 301 |
287 test_stream_.reset(CreateStream(kTestChannelLayout, | 302 test_stream = CreateStream(kTestChannelLayout, |
288 kOverMinLatencyPacketSize)); | 303 kOverMinLatencyPacketSize); |
289 ASSERT_TRUE(test_stream_->Open()); | 304 ASSERT_TRUE(test_stream->Open()); |
290 | 305 |
291 // Now close it and test that everything was released. | 306 // Now close it and test that everything was released. |
292 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) | 307 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) |
293 .WillOnce(Return(0)); | 308 .WillOnce(Return(0)); |
294 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 309 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
295 .WillOnce(Return(kTestDeviceName)); | 310 .WillOnce(Return(kTestDeviceName)); |
296 EXPECT_CALL(mock_manager(), ReleaseOutputStream(test_stream_.get())); | 311 test_stream->Close(); |
297 test_stream_->Close(); | |
298 | 312 |
299 Mock::VerifyAndClear(&mock_alsa_wrapper_); | 313 Mock::VerifyAndClear(&mock_alsa_wrapper_); |
300 Mock::VerifyAndClear(mock_manager_.get()); | 314 Mock::VerifyAndClear(mock_manager_.get()); |
301 } | 315 } |
302 | 316 |
303 TEST_F(AlsaPcmOutputStreamTest, OpenClose) { | 317 TEST_F(AlsaPcmOutputStreamTest, OpenClose) { |
304 int64 expected_micros = 2 * | 318 int64 expected_micros = 2 * |
305 AlsaPcmOutputStream::FramesToMicros(kTestPacketSize / kTestBytesPerFrame, | 319 AlsaPcmOutputStream::FramesToMicros(kTestPacketSize / kTestBytesPerFrame, |
306 kTestSampleRate); | 320 kTestSampleRate); |
307 | 321 |
(...skipping 13 matching lines...) Expand all Loading... |
321 kTestSampleRate, | 335 kTestSampleRate, |
322 1, | 336 1, |
323 expected_micros)) | 337 expected_micros)) |
324 .WillOnce(Return(0)); | 338 .WillOnce(Return(0)); |
325 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(kFakeHandle, _, _)) | 339 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(kFakeHandle, _, _)) |
326 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), | 340 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), |
327 SetArgumentPointee<2>(kTestFramesPerPacket / 2), | 341 SetArgumentPointee<2>(kTestFramesPerPacket / 2), |
328 Return(0))); | 342 Return(0))); |
329 | 343 |
330 // Open the stream. | 344 // Open the stream. |
331 ASSERT_TRUE(test_stream_->Open()); | 345 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 346 ASSERT_TRUE(test_stream->Open()); |
332 | 347 |
333 EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream_->state()); | 348 EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream->state()); |
334 EXPECT_EQ(kFakeHandle, test_stream_->playback_handle_); | 349 EXPECT_EQ(kFakeHandle, test_stream->playback_handle_); |
335 EXPECT_EQ(kTestFramesPerPacket, test_stream_->frames_per_packet_); | 350 EXPECT_EQ(kTestFramesPerPacket, test_stream->frames_per_packet_); |
336 EXPECT_TRUE(test_stream_->buffer_.get()); | 351 EXPECT_TRUE(test_stream->buffer_.get()); |
337 EXPECT_FALSE(test_stream_->stop_stream_); | 352 EXPECT_FALSE(test_stream->stop_stream_); |
338 | 353 |
339 // Now close it and test that everything was released. | 354 // Now close it and test that everything was released. |
340 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) | 355 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) |
341 .WillOnce(Return(0)); | 356 .WillOnce(Return(0)); |
342 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 357 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
343 .WillOnce(Return(kTestDeviceName)); | 358 .WillOnce(Return(kTestDeviceName)); |
344 EXPECT_CALL(mock_manager(), ReleaseOutputStream(test_stream_.get())); | 359 test_stream->Close(); |
345 test_stream_->Close(); | |
346 | |
347 EXPECT_TRUE(test_stream_->playback_handle_ == NULL); | |
348 EXPECT_FALSE(test_stream_->buffer_.get()); | |
349 EXPECT_TRUE(test_stream_->stop_stream_); | |
350 } | 360 } |
351 | 361 |
352 TEST_F(AlsaPcmOutputStreamTest, PcmOpenFailed) { | 362 TEST_F(AlsaPcmOutputStreamTest, PcmOpenFailed) { |
353 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 363 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
354 .WillOnce(Return(kTestFailedErrno)); | 364 .WillOnce(Return(kTestFailedErrno)); |
355 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) | 365 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) |
356 .WillOnce(Return(kDummyMessage)); | 366 .WillOnce(Return(kDummyMessage)); |
357 | 367 |
358 ASSERT_FALSE(test_stream_->Open()); | 368 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
359 ASSERT_EQ(AlsaPcmOutputStream::kInError, test_stream_->state()); | 369 ASSERT_FALSE(test_stream->Open()); |
| 370 ASSERT_EQ(AlsaPcmOutputStream::kInError, test_stream->state()); |
360 | 371 |
361 // Ensure internal state is set for a no-op stream if PcmOpen() failes. | 372 // Ensure internal state is set for a no-op stream if PcmOpen() failes. |
362 EXPECT_TRUE(test_stream_->stop_stream_); | 373 EXPECT_TRUE(test_stream->stop_stream_); |
363 EXPECT_TRUE(test_stream_->playback_handle_ == NULL); | 374 EXPECT_TRUE(test_stream->playback_handle_ == NULL); |
364 EXPECT_FALSE(test_stream_->buffer_.get()); | 375 EXPECT_FALSE(test_stream->buffer_.get()); |
365 | 376 |
366 // Close the stream since we opened it to make destruction happy. | 377 // Close the stream since we opened it to make destruction happy. |
367 EXPECT_CALL(mock_manager(), ReleaseOutputStream(test_stream_.get())); | 378 test_stream->Close(); |
368 test_stream_->Close(); | |
369 } | 379 } |
370 | 380 |
371 TEST_F(AlsaPcmOutputStreamTest, PcmSetParamsFailed) { | 381 TEST_F(AlsaPcmOutputStreamTest, PcmSetParamsFailed) { |
372 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 382 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
373 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), | 383 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), |
374 Return(0))); | 384 Return(0))); |
375 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) | 385 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) |
376 .WillOnce(Return(kTestFailedErrno)); | 386 .WillOnce(Return(kTestFailedErrno)); |
377 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) | 387 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) |
378 .WillOnce(Return(0)); | 388 .WillOnce(Return(0)); |
379 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 389 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
380 .WillOnce(Return(kTestDeviceName)); | 390 .WillOnce(Return(kTestDeviceName)); |
381 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) | 391 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) |
382 .WillOnce(Return(kDummyMessage)); | 392 .WillOnce(Return(kDummyMessage)); |
383 | 393 |
384 // If open fails, the stream stays in kCreated because it has effectively had | 394 // If open fails, the stream stays in kCreated because it has effectively had |
385 // no changes. | 395 // no changes. |
386 ASSERT_FALSE(test_stream_->Open()); | 396 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
387 EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream_->state()); | 397 ASSERT_FALSE(test_stream->Open()); |
| 398 EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream->state()); |
388 | 399 |
389 // Ensure internal state is set for a no-op stream if PcmSetParams() failes. | 400 // Ensure internal state is set for a no-op stream if PcmSetParams() failes. |
390 EXPECT_TRUE(test_stream_->stop_stream_); | 401 EXPECT_TRUE(test_stream->stop_stream_); |
391 EXPECT_TRUE(test_stream_->playback_handle_ == NULL); | 402 EXPECT_TRUE(test_stream->playback_handle_ == NULL); |
392 EXPECT_FALSE(test_stream_->buffer_.get()); | 403 EXPECT_FALSE(test_stream->buffer_.get()); |
393 | 404 |
394 // Close the stream since we opened it to make destruction happy. | 405 // Close the stream since we opened it to make destruction happy. |
395 EXPECT_CALL(mock_manager(), ReleaseOutputStream(test_stream_.get())); | 406 test_stream->Close(); |
396 test_stream_->Close(); | |
397 } | 407 } |
398 | 408 |
399 TEST_F(AlsaPcmOutputStreamTest, StartStop) { | 409 TEST_F(AlsaPcmOutputStreamTest, StartStop) { |
400 // Open() call opens the playback device, sets the parameters, posts a task | 410 // Open() call opens the playback device, sets the parameters, posts a task |
401 // with the resulting configuration data, and transitions the object state to | 411 // with the resulting configuration data, and transitions the object state to |
402 // kIsOpened. | 412 // kIsOpened. |
403 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 413 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
404 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), | 414 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), |
405 Return(0))); | 415 Return(0))); |
406 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) | 416 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) |
407 .WillOnce(Return(0)); | 417 .WillOnce(Return(0)); |
408 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) | 418 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) |
409 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), | 419 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), |
410 SetArgumentPointee<2>(kTestFramesPerPacket / 2), | 420 SetArgumentPointee<2>(kTestFramesPerPacket / 2), |
411 Return(0))); | 421 Return(0))); |
412 | 422 |
413 // Open the stream. | 423 // Open the stream. |
414 ASSERT_TRUE(test_stream_->Open()); | 424 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 425 ASSERT_TRUE(test_stream->Open()); |
415 | 426 |
416 // Expect Device setup. | 427 // Expect Device setup. |
417 EXPECT_CALL(mock_alsa_wrapper_, PcmDrop(kFakeHandle)) | 428 EXPECT_CALL(mock_alsa_wrapper_, PcmDrop(kFakeHandle)) |
418 .WillOnce(Return(0)); | 429 .WillOnce(Return(0)); |
419 EXPECT_CALL(mock_alsa_wrapper_, PcmPrepare(kFakeHandle)) | 430 EXPECT_CALL(mock_alsa_wrapper_, PcmPrepare(kFakeHandle)) |
420 .WillOnce(Return(0)); | 431 .WillOnce(Return(0)); |
421 | 432 |
422 // Expect the pre-roll. | 433 // Expect the pre-roll. |
423 MockAudioSourceCallback mock_callback; | 434 MockAudioSourceCallback mock_callback; |
424 EXPECT_CALL(mock_alsa_wrapper_, PcmState(kFakeHandle)) | 435 EXPECT_CALL(mock_alsa_wrapper_, PcmState(kFakeHandle)) |
425 .Times(3) | 436 .Times(3) |
426 .WillRepeatedly(Return(SND_PCM_STATE_RUNNING)); | 437 .WillRepeatedly(Return(SND_PCM_STATE_RUNNING)); |
427 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(kFakeHandle, _)) | 438 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(kFakeHandle, _)) |
428 .Times(2) | 439 .Times(2) |
429 .WillRepeatedly(DoAll(SetArgumentPointee<1>(0), Return(0))); | 440 .WillRepeatedly(DoAll(SetArgumentPointee<1>(0), Return(0))); |
430 EXPECT_CALL(mock_callback, | 441 EXPECT_CALL(mock_callback, |
431 OnMoreData(test_stream_.get(), _, kTestPacketSize, _)) | 442 OnMoreData(test_stream, _, kTestPacketSize, _)) |
432 .Times(2) | 443 .Times(2) |
433 .WillOnce(Return(kTestPacketSize)) | 444 .WillOnce(Return(kTestPacketSize)) |
434 .WillOnce(Return(0)); | 445 .WillOnce(Return(0)); |
435 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) | 446 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) |
436 .WillOnce(Return(kTestFramesPerPacket)); | 447 .WillOnce(Return(kTestFramesPerPacket)); |
437 | 448 |
438 // Expect scheduling. | 449 // Expect scheduling. |
439 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) | 450 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) |
440 .Times(AtLeast(3)) | 451 .Times(AtLeast(3)) |
441 .WillOnce(Return(kTestFramesPerPacket)) // Buffer is empty. | 452 .WillOnce(Return(kTestFramesPerPacket)) // Buffer is empty. |
442 .WillOnce(Return(kTestFramesPerPacket)) | 453 .WillOnce(Return(kTestFramesPerPacket)) |
443 .WillRepeatedly(DoAll(InvokeWithoutArgs(&message_loop_, | 454 .WillRepeatedly(DoAll(InvokeWithoutArgs(&message_loop_, |
444 &MessageLoop::QuitNow), | 455 &MessageLoop::QuitNow), |
445 Return(0))); // Buffer is full. | 456 Return(0))); // Buffer is full. |
446 | 457 |
447 test_stream_->Start(&mock_callback); | 458 test_stream->Start(&mock_callback); |
448 message_loop_.RunAllPending(); | 459 message_loop_.RunAllPending(); |
449 | 460 |
450 EXPECT_CALL(mock_manager(), ReleaseOutputStream(test_stream_.get())); | |
451 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) | 461 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) |
452 .WillOnce(Return(0)); | 462 .WillOnce(Return(0)); |
453 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 463 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
454 .WillOnce(Return(kTestDeviceName)); | 464 .WillOnce(Return(kTestDeviceName)); |
455 test_stream_->Close(); | 465 test_stream->Close(); |
456 } | 466 } |
457 | 467 |
458 TEST_F(AlsaPcmOutputStreamTest, WritePacket_FinishedPacket) { | 468 TEST_F(AlsaPcmOutputStreamTest, WritePacket_FinishedPacket) { |
459 InitBuffer(); | 469 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 470 InitBuffer(test_stream); |
460 | 471 |
461 // Nothing should happen. Don't set any expectations and Our strict mocks | 472 // Nothing should happen. Don't set any expectations and Our strict mocks |
462 // should verify most of this. | 473 // should verify most of this. |
463 | 474 |
464 // Test empty buffer. | 475 // Test empty buffer. |
465 test_stream_->buffer_->Clear(); | 476 test_stream->buffer_->Clear(); |
466 test_stream_->WritePacket(); | 477 test_stream->WritePacket(); |
| 478 test_stream->Close(); |
467 } | 479 } |
468 | 480 |
469 TEST_F(AlsaPcmOutputStreamTest, WritePacket_NormalPacket) { | 481 TEST_F(AlsaPcmOutputStreamTest, WritePacket_NormalPacket) { |
470 InitBuffer(); | 482 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 483 InitBuffer(test_stream); |
471 | 484 |
472 // Write a little less than half the data. | 485 // Write a little less than half the data. |
473 int written = packet_->GetDataSize() / kTestBytesPerFrame / 2 - 1; | 486 int written = packet_->GetDataSize() / kTestBytesPerFrame / 2 - 1; |
474 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(_, packet_->GetData(), _)) | 487 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(_, packet_->GetData(), _)) |
475 .WillOnce(Return(written)); | 488 .WillOnce(Return(written)); |
476 | 489 |
477 test_stream_->WritePacket(); | 490 test_stream->WritePacket(); |
478 | 491 |
479 ASSERT_EQ(test_stream_->buffer_->forward_bytes(), | 492 ASSERT_EQ(test_stream->buffer_->forward_bytes(), |
480 packet_->GetDataSize() - written * kTestBytesPerFrame); | 493 packet_->GetDataSize() - written * kTestBytesPerFrame); |
481 | 494 |
482 // Write the rest. | 495 // Write the rest. |
483 EXPECT_CALL(mock_alsa_wrapper_, | 496 EXPECT_CALL(mock_alsa_wrapper_, |
484 PcmWritei(_, packet_->GetData() + written * kTestBytesPerFrame, | 497 PcmWritei(_, packet_->GetData() + written * kTestBytesPerFrame, |
485 _)) | 498 _)) |
486 .WillOnce(Return(packet_->GetDataSize() / kTestBytesPerFrame - written)); | 499 .WillOnce(Return(packet_->GetDataSize() / kTestBytesPerFrame - written)); |
487 test_stream_->WritePacket(); | 500 test_stream->WritePacket(); |
488 EXPECT_EQ(0u, test_stream_->buffer_->forward_bytes()); | 501 EXPECT_EQ(0u, test_stream->buffer_->forward_bytes()); |
| 502 test_stream->Close(); |
489 } | 503 } |
490 | 504 |
491 TEST_F(AlsaPcmOutputStreamTest, WritePacket_WriteFails) { | 505 TEST_F(AlsaPcmOutputStreamTest, WritePacket_WriteFails) { |
492 InitBuffer(); | 506 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 507 InitBuffer(test_stream); |
493 | 508 |
494 // Fail due to a recoverable error and see that PcmRecover code path | 509 // Fail due to a recoverable error and see that PcmRecover code path |
495 // continues normally. | 510 // continues normally. |
496 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(_, _, _)) | 511 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(_, _, _)) |
497 .WillOnce(Return(-EINTR)); | 512 .WillOnce(Return(-EINTR)); |
498 EXPECT_CALL(mock_alsa_wrapper_, PcmRecover(_, _, _)) | 513 EXPECT_CALL(mock_alsa_wrapper_, PcmRecover(_, _, _)) |
499 .WillOnce(Return(packet_->GetDataSize() / kTestBytesPerFrame / 2 - 1)); | 514 .WillOnce(Return(packet_->GetDataSize() / kTestBytesPerFrame / 2 - 1)); |
500 | 515 |
501 test_stream_->WritePacket(); | 516 test_stream->WritePacket(); |
502 | 517 |
503 ASSERT_EQ(test_stream_->buffer_->forward_bytes(), | 518 ASSERT_EQ(test_stream->buffer_->forward_bytes(), |
504 packet_->GetDataSize() / 2 + kTestBytesPerFrame); | 519 packet_->GetDataSize() / 2 + kTestBytesPerFrame); |
505 | 520 |
506 // Fail the next write, and see that stop_stream_ is set. | 521 // Fail the next write, and see that stop_stream_ is set. |
507 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(_, _, _)) | 522 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(_, _, _)) |
508 .WillOnce(Return(kTestFailedErrno)); | 523 .WillOnce(Return(kTestFailedErrno)); |
509 EXPECT_CALL(mock_alsa_wrapper_, PcmRecover(_, _, _)) | 524 EXPECT_CALL(mock_alsa_wrapper_, PcmRecover(_, _, _)) |
510 .WillOnce(Return(kTestFailedErrno)); | 525 .WillOnce(Return(kTestFailedErrno)); |
511 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) | 526 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) |
512 .WillOnce(Return(kDummyMessage)); | 527 .WillOnce(Return(kDummyMessage)); |
513 test_stream_->WritePacket(); | 528 test_stream->WritePacket(); |
514 EXPECT_EQ(test_stream_->buffer_->forward_bytes(), | 529 EXPECT_EQ(test_stream->buffer_->forward_bytes(), |
515 packet_->GetDataSize() / 2 + kTestBytesPerFrame); | 530 packet_->GetDataSize() / 2 + kTestBytesPerFrame); |
516 EXPECT_TRUE(test_stream_->stop_stream_); | 531 EXPECT_TRUE(test_stream->stop_stream_); |
| 532 test_stream->Close(); |
517 } | 533 } |
518 | 534 |
519 TEST_F(AlsaPcmOutputStreamTest, WritePacket_StopStream) { | 535 TEST_F(AlsaPcmOutputStreamTest, WritePacket_StopStream) { |
520 InitBuffer(); | 536 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 537 InitBuffer(test_stream); |
521 | 538 |
522 // No expectations set on the strict mock because nothing should be called. | 539 // No expectations set on the strict mock because nothing should be called. |
523 test_stream_->stop_stream_ = true; | 540 test_stream->stop_stream_ = true; |
524 test_stream_->WritePacket(); | 541 test_stream->WritePacket(); |
525 EXPECT_EQ(0u, test_stream_->buffer_->forward_bytes()); | 542 EXPECT_EQ(0u, test_stream->buffer_->forward_bytes()); |
| 543 test_stream->Close(); |
526 } | 544 } |
527 | 545 |
528 TEST_F(AlsaPcmOutputStreamTest, BufferPacket) { | 546 TEST_F(AlsaPcmOutputStreamTest, BufferPacket) { |
529 InitBuffer(); | 547 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
530 test_stream_->buffer_->Clear(); | 548 InitBuffer(test_stream); |
| 549 test_stream->buffer_->Clear(); |
531 | 550 |
532 MockAudioSourceCallback mock_callback; | 551 MockAudioSourceCallback mock_callback; |
533 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 552 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
534 .WillOnce(Return(SND_PCM_STATE_RUNNING)); | 553 .WillOnce(Return(SND_PCM_STATE_RUNNING)); |
535 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) | 554 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) |
536 .WillOnce(DoAll(SetArgumentPointee<1>(1), Return(0))); | 555 .WillOnce(DoAll(SetArgumentPointee<1>(1), Return(0))); |
537 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 556 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
538 .WillRepeatedly(Return(0)); // Buffer is full. | 557 .WillRepeatedly(Return(0)); // Buffer is full. |
539 | 558 |
540 // Return a partially filled packet. | 559 // Return a partially filled packet. |
541 EXPECT_CALL(mock_callback, | 560 EXPECT_CALL(mock_callback, |
542 OnMoreData(test_stream_.get(), _, _, _)) | 561 OnMoreData(test_stream, _, _, _)) |
543 .WillOnce(Return(10)); | 562 .WillOnce(Return(10)); |
544 | 563 |
545 bool source_exhausted; | 564 bool source_exhausted; |
546 test_stream_->set_source_callback(&mock_callback); | 565 test_stream->set_source_callback(&mock_callback); |
547 test_stream_->packet_size_ = kTestPacketSize; | 566 test_stream->packet_size_ = kTestPacketSize; |
548 test_stream_->BufferPacket(&source_exhausted); | 567 test_stream->BufferPacket(&source_exhausted); |
549 | 568 |
550 EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes()); | 569 EXPECT_EQ(10u, test_stream->buffer_->forward_bytes()); |
551 EXPECT_FALSE(source_exhausted); | 570 EXPECT_FALSE(source_exhausted); |
| 571 test_stream->Close(); |
552 } | 572 } |
553 | 573 |
554 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) { | 574 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) { |
555 InitBuffer(); | 575 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
556 test_stream_->buffer_->Clear(); | 576 InitBuffer(test_stream); |
| 577 test_stream->buffer_->Clear(); |
557 | 578 |
558 // Simulate where the underrun has occurred right after checking the delay. | 579 // Simulate where the underrun has occurred right after checking the delay. |
559 MockAudioSourceCallback mock_callback; | 580 MockAudioSourceCallback mock_callback; |
560 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 581 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
561 .WillOnce(Return(SND_PCM_STATE_RUNNING)); | 582 .WillOnce(Return(SND_PCM_STATE_RUNNING)); |
562 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) | 583 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) |
563 .WillOnce(DoAll(SetArgumentPointee<1>(-1), Return(0))); | 584 .WillOnce(DoAll(SetArgumentPointee<1>(-1), Return(0))); |
564 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 585 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
565 .WillRepeatedly(Return(0)); // Buffer is full. | 586 .WillRepeatedly(Return(0)); // Buffer is full. |
566 EXPECT_CALL(mock_callback, | 587 EXPECT_CALL(mock_callback, OnMoreData(test_stream, _, _, _)) |
567 OnMoreData(test_stream_.get(), _, _, _)) | |
568 .WillOnce(Return(10)); | 588 .WillOnce(Return(10)); |
569 | 589 |
570 bool source_exhausted; | 590 bool source_exhausted; |
571 test_stream_->set_source_callback(&mock_callback); | 591 test_stream->set_source_callback(&mock_callback); |
572 test_stream_->packet_size_ = kTestPacketSize; | 592 test_stream->packet_size_ = kTestPacketSize; |
573 test_stream_->BufferPacket(&source_exhausted); | 593 test_stream->BufferPacket(&source_exhausted); |
574 | 594 |
575 EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes()); | 595 EXPECT_EQ(10u, test_stream->buffer_->forward_bytes()); |
576 EXPECT_FALSE(source_exhausted); | 596 EXPECT_FALSE(source_exhausted); |
| 597 test_stream->Close(); |
577 } | 598 } |
578 | 599 |
579 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) { | 600 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) { |
580 InitBuffer(); | 601 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
581 test_stream_->buffer_->Clear(); | 602 InitBuffer(test_stream); |
| 603 test_stream->buffer_->Clear(); |
582 | 604 |
583 // If ALSA has underrun then we should assume a delay of zero. | 605 // If ALSA has underrun then we should assume a delay of zero. |
584 MockAudioSourceCallback mock_callback; | 606 MockAudioSourceCallback mock_callback; |
585 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 607 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
586 .WillOnce(Return(SND_PCM_STATE_XRUN)); | 608 .WillOnce(Return(SND_PCM_STATE_XRUN)); |
587 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 609 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
588 .WillRepeatedly(Return(0)); // Buffer is full. | 610 .WillRepeatedly(Return(0)); // Buffer is full. |
589 EXPECT_CALL(mock_callback, | 611 EXPECT_CALL(mock_callback, |
590 OnMoreData(test_stream_.get(), _, _, AllOf( | 612 OnMoreData(test_stream, _, _, AllOf( |
591 Field(&AudioBuffersState::pending_bytes, 0), | 613 Field(&AudioBuffersState::pending_bytes, 0), |
592 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) | 614 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) |
593 .WillOnce(Return(10)); | 615 .WillOnce(Return(10)); |
594 | 616 |
595 bool source_exhausted; | 617 bool source_exhausted; |
596 test_stream_->set_source_callback(&mock_callback); | 618 test_stream->set_source_callback(&mock_callback); |
597 test_stream_->packet_size_ = kTestPacketSize; | 619 test_stream->packet_size_ = kTestPacketSize; |
598 test_stream_->BufferPacket(&source_exhausted); | 620 test_stream->BufferPacket(&source_exhausted); |
599 | 621 |
600 EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes()); | 622 EXPECT_EQ(10u, test_stream->buffer_->forward_bytes()); |
601 EXPECT_FALSE(source_exhausted); | 623 EXPECT_FALSE(source_exhausted); |
| 624 test_stream->Close(); |
602 } | 625 } |
603 | 626 |
604 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_FullBuffer) { | 627 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_FullBuffer) { |
605 InitBuffer(); | 628 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 629 InitBuffer(test_stream); |
606 // No expectations set on the strict mock because nothing should be called. | 630 // No expectations set on the strict mock because nothing should be called. |
607 bool source_exhausted; | 631 bool source_exhausted; |
608 test_stream_->packet_size_ = kTestPacketSize; | 632 test_stream->packet_size_ = kTestPacketSize; |
609 test_stream_->BufferPacket(&source_exhausted); | 633 test_stream->BufferPacket(&source_exhausted); |
610 EXPECT_EQ(kTestPacketSize, test_stream_->buffer_->forward_bytes()); | 634 EXPECT_EQ(kTestPacketSize, test_stream->buffer_->forward_bytes()); |
611 EXPECT_FALSE(source_exhausted); | 635 EXPECT_FALSE(source_exhausted); |
| 636 test_stream->Close(); |
612 } | 637 } |
613 | 638 |
614 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_DeviceSelect) { | 639 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_DeviceSelect) { |
615 // Try channels from 1 -> 9. and see that we get the more specific surroundXX | 640 // Try channels from 1 -> 9. and see that we get the more specific surroundXX |
616 // device opened for channels 4-8. For all other channels, the device should | 641 // device opened for channels 4-8. For all other channels, the device should |
617 // default to |AlsaPcmOutputStream::kDefaultDevice|. We should also not | 642 // default to |AlsaPcmOutputStream::kDefaultDevice|. We should also not |
618 // downmix any channel in this case because downmixing is only defined for | 643 // downmix any channel in this case because downmixing is only defined for |
619 // channels 4-8, which we are guaranteeing to work. | 644 // channels 4-8, which we are guaranteeing to work. |
620 // | 645 // |
621 // Note that the loop starts at "1", so the first parameter is ignored in | 646 // Note that the loop starts at "1", so the first parameter is ignored in |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 PcmSetParams(kFakeHandle, _, _, i, _, _, _)) | 688 PcmSetParams(kFakeHandle, _, _, i, _, _, _)) |
664 .WillOnce(Return(0)); | 689 .WillOnce(Return(0)); |
665 | 690 |
666 // The parameters are specified by ALSA documentation, and are in constants | 691 // The parameters are specified by ALSA documentation, and are in constants |
667 // in the implementation files. | 692 // in the implementation files. |
668 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("IOID"))) | 693 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("IOID"))) |
669 .WillRepeatedly(Invoke(OutputHint)); | 694 .WillRepeatedly(Invoke(OutputHint)); |
670 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("NAME"))) | 695 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("NAME"))) |
671 .WillRepeatedly(Invoke(EchoHint)); | 696 .WillRepeatedly(Invoke(EchoHint)); |
672 | 697 |
673 test_stream_.reset(CreateStream(kExpectedLayouts[i])); | 698 AlsaPcmOutputStream* test_stream = CreateStream(kExpectedLayouts[i]); |
674 EXPECT_TRUE(test_stream_->AutoSelectDevice(i)); | 699 EXPECT_TRUE(test_stream->AutoSelectDevice(i)); |
675 EXPECT_EQ(kExpectedDownmix[i], test_stream_->should_downmix_); | 700 EXPECT_EQ(kExpectedDownmix[i], test_stream->should_downmix_); |
676 | 701 |
677 Mock::VerifyAndClearExpectations(&mock_alsa_wrapper_); | 702 Mock::VerifyAndClearExpectations(&mock_alsa_wrapper_); |
678 Mock::VerifyAndClearExpectations(mock_manager_.get()); | 703 Mock::VerifyAndClearExpectations(mock_manager_.get()); |
| 704 test_stream->Close(); |
679 } | 705 } |
680 } | 706 } |
681 | 707 |
682 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_FallbackDevices) { | 708 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_FallbackDevices) { |
683 using std::string; | 709 using std::string; |
684 | 710 |
685 // If there are problems opening a multi-channel device, it the fallbacks | 711 // If there are problems opening a multi-channel device, it the fallbacks |
686 // operations should be as follows. Assume the multi-channel device name is | 712 // operations should be as follows. Assume the multi-channel device name is |
687 // surround50: | 713 // surround50: |
688 // | 714 // |
(...skipping 24 matching lines...) Expand all Loading... |
713 InSequence s; | 739 InSequence s; |
714 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(first_try.c_str()), _, _)) | 740 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(first_try.c_str()), _, _)) |
715 .WillOnce(Return(kTestFailedErrno)); | 741 .WillOnce(Return(kTestFailedErrno)); |
716 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(second_try.c_str()), _, _)) | 742 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(second_try.c_str()), _, _)) |
717 .WillOnce(Return(kTestFailedErrno)); | 743 .WillOnce(Return(kTestFailedErrno)); |
718 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(third_try.c_str()), _, _)) | 744 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(third_try.c_str()), _, _)) |
719 .WillOnce(Return(kTestFailedErrno)); | 745 .WillOnce(Return(kTestFailedErrno)); |
720 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(fourth_try.c_str()), _, _)) | 746 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(fourth_try.c_str()), _, _)) |
721 .WillOnce(Return(kTestFailedErrno)); | 747 .WillOnce(Return(kTestFailedErrno)); |
722 | 748 |
723 test_stream_.reset(CreateStream(CHANNEL_LAYOUT_5POINT0)); | 749 AlsaPcmOutputStream* test_stream = CreateStream(CHANNEL_LAYOUT_5POINT0); |
724 EXPECT_FALSE(test_stream_->AutoSelectDevice(5)); | 750 EXPECT_FALSE(test_stream->AutoSelectDevice(5)); |
| 751 test_stream->Close(); |
725 } | 752 } |
726 | 753 |
727 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_HintFail) { | 754 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_HintFail) { |
728 // Should get |kDefaultDevice|, and force a 2-channel downmix on a failure to | 755 // Should get |kDefaultDevice|, and force a 2-channel downmix on a failure to |
729 // enumerate devices. | 756 // enumerate devices. |
730 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameHint(_, _, _)) | 757 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameHint(_, _, _)) |
731 .WillRepeatedly(Return(kTestFailedErrno)); | 758 .WillRepeatedly(Return(kTestFailedErrno)); |
732 EXPECT_CALL(mock_alsa_wrapper_, | 759 EXPECT_CALL(mock_alsa_wrapper_, |
733 PcmOpen(_, StrEq(AlsaPcmOutputStream::kDefaultDevice), _, _)) | 760 PcmOpen(_, StrEq(AlsaPcmOutputStream::kDefaultDevice), _, _)) |
734 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); | 761 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); |
735 EXPECT_CALL(mock_alsa_wrapper_, | 762 EXPECT_CALL(mock_alsa_wrapper_, |
736 PcmSetParams(kFakeHandle, _, _, 2, _, _, _)) | 763 PcmSetParams(kFakeHandle, _, _, 2, _, _, _)) |
737 .WillOnce(Return(0)); | 764 .WillOnce(Return(0)); |
738 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) | 765 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) |
739 .WillOnce(Return(kDummyMessage)); | 766 .WillOnce(Return(kDummyMessage)); |
740 | 767 |
741 test_stream_.reset(CreateStream(CHANNEL_LAYOUT_5POINT0)); | 768 AlsaPcmOutputStream* test_stream = CreateStream(CHANNEL_LAYOUT_5POINT0); |
742 EXPECT_TRUE(test_stream_->AutoSelectDevice(5)); | 769 EXPECT_TRUE(test_stream->AutoSelectDevice(5)); |
743 EXPECT_TRUE(test_stream_->should_downmix_); | 770 EXPECT_TRUE(test_stream->should_downmix_); |
| 771 test_stream->Close(); |
744 } | 772 } |
745 | 773 |
746 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_StopStream) { | 774 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_StopStream) { |
747 InitBuffer(); | 775 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
748 test_stream_->stop_stream_ = true; | 776 InitBuffer(test_stream); |
| 777 test_stream->stop_stream_ = true; |
749 bool source_exhausted; | 778 bool source_exhausted; |
750 test_stream_->BufferPacket(&source_exhausted); | 779 test_stream->BufferPacket(&source_exhausted); |
751 EXPECT_EQ(0u, test_stream_->buffer_->forward_bytes()); | 780 EXPECT_EQ(0u, test_stream->buffer_->forward_bytes()); |
752 EXPECT_TRUE(source_exhausted); | 781 EXPECT_TRUE(source_exhausted); |
| 782 test_stream->Close(); |
753 } | 783 } |
754 | 784 |
755 TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite) { | 785 TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite) { |
756 test_stream_->TransitionTo(AlsaPcmOutputStream::kIsOpened); | 786 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
757 test_stream_->TransitionTo(AlsaPcmOutputStream::kIsPlaying); | 787 test_stream->TransitionTo(AlsaPcmOutputStream::kIsOpened); |
758 | 788 test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying); |
759 InitBuffer(); | 789 DLOG(WARNING) << test_stream->state(); |
760 | 790 InitBuffer(test_stream); |
| 791 DLOG(WARNING) << test_stream->state(); |
761 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 792 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
762 .WillOnce(Return(10)); | 793 .WillOnce(Return(10)); |
763 test_stream_->ScheduleNextWrite(false); | 794 test_stream->ScheduleNextWrite(false); |
764 | 795 DLOG(WARNING) << test_stream->state(); |
765 // TODO(sergeyu): Figure out how to check that the task has been added to the | 796 // TODO(sergeyu): Figure out how to check that the task has been added to the |
766 // message loop. | 797 // message loop. |
767 | 798 |
768 // Cleanup the message queue. Currently ~MessageQueue() doesn't free pending | 799 // Cleanup the message queue. Currently ~MessageQueue() doesn't free pending |
769 // tasks unless running on valgrind. The code below is needed to keep | 800 // tasks unless running on valgrind. The code below is needed to keep |
770 // heapcheck happy. | 801 // heapcheck happy. |
771 test_stream_->stop_stream_ = true; | |
772 | 802 |
773 test_stream_->TransitionTo(AlsaPcmOutputStream::kIsClosed); | 803 test_stream->stop_stream_ = true; |
| 804 DLOG(WARNING) << test_stream->state(); |
| 805 test_stream->TransitionTo(AlsaPcmOutputStream::kIsClosed); |
| 806 DLOG(WARNING) << test_stream->state(); |
| 807 test_stream->Close(); |
774 } | 808 } |
775 | 809 |
776 TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite_StopStream) { | 810 TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite_StopStream) { |
777 test_stream_->TransitionTo(AlsaPcmOutputStream::kIsOpened); | 811 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
778 test_stream_->TransitionTo(AlsaPcmOutputStream::kIsPlaying); | 812 test_stream->TransitionTo(AlsaPcmOutputStream::kIsOpened); |
| 813 test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying); |
779 | 814 |
780 InitBuffer(); | 815 InitBuffer(test_stream); |
781 | 816 |
782 test_stream_->stop_stream_ = true; | 817 test_stream->stop_stream_ = true; |
783 test_stream_->ScheduleNextWrite(true); | 818 test_stream->ScheduleNextWrite(true); |
784 | 819 |
785 // TODO(ajwong): Find a way to test whether or not another task has been | 820 // TODO(ajwong): Find a way to test whether or not another task has been |
786 // posted so we can verify that the Alsa code will indeed break the task | 821 // posted so we can verify that the Alsa code will indeed break the task |
787 // posting loop. | 822 // posting loop. |
788 | 823 |
789 test_stream_->TransitionTo(AlsaPcmOutputStream::kIsClosed); | 824 test_stream->TransitionTo(AlsaPcmOutputStream::kIsClosed); |
| 825 test_stream->Close(); |
790 } | 826 } |
OLD | NEW |