| 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/strings/stringprintf.h" | 6 #include "base/strings/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 14 matching lines...) Expand all Loading... |
| 25 using testing::Return; | 25 using testing::Return; |
| 26 using testing::SetArgumentPointee; | 26 using testing::SetArgumentPointee; |
| 27 using testing::StrictMock; | 27 using testing::StrictMock; |
| 28 using testing::StrEq; | 28 using testing::StrEq; |
| 29 using testing::Unused; | 29 using testing::Unused; |
| 30 | 30 |
| 31 namespace media { | 31 namespace media { |
| 32 | 32 |
| 33 class MockAlsaWrapper : public AlsaWrapper { | 33 class MockAlsaWrapper : public AlsaWrapper { |
| 34 public: | 34 public: |
| 35 MOCK_METHOD3(DeviceNameHint, int(int card, | 35 MOCK_METHOD3(DeviceNameHint, int(int card, const char* iface, void*** hints)); |
| 36 const char* iface, | |
| 37 void*** hints)); | |
| 38 MOCK_METHOD2(DeviceNameGetHint, char*(const void* hint, const char* id)); | 36 MOCK_METHOD2(DeviceNameGetHint, char*(const void* hint, const char* id)); |
| 39 MOCK_METHOD1(DeviceNameFreeHint, int(void** hints)); | 37 MOCK_METHOD1(DeviceNameFreeHint, int(void** hints)); |
| 40 | 38 |
| 41 MOCK_METHOD4(PcmOpen, int(snd_pcm_t** handle, const char* name, | 39 MOCK_METHOD4(PcmOpen, int(snd_pcm_t** handle, const char* name, |
| 42 snd_pcm_stream_t stream, int mode)); | 40 snd_pcm_stream_t stream, int mode)); |
| 43 MOCK_METHOD1(PcmClose, int(snd_pcm_t* handle)); | 41 MOCK_METHOD1(PcmClose, int(snd_pcm_t* handle)); |
| 44 MOCK_METHOD1(PcmPrepare, int(snd_pcm_t* handle)); | 42 MOCK_METHOD1(PcmPrepare, int(snd_pcm_t* handle)); |
| 45 MOCK_METHOD1(PcmDrop, int(snd_pcm_t* handle)); | 43 MOCK_METHOD1(PcmDrop, int(snd_pcm_t* handle)); |
| 46 MOCK_METHOD2(PcmDelay, int(snd_pcm_t* handle, snd_pcm_sframes_t* delay)); | 44 MOCK_METHOD2(PcmDelay, int(snd_pcm_t* handle, snd_pcm_sframes_t* delay)); |
| 47 MOCK_METHOD3(PcmWritei, snd_pcm_sframes_t(snd_pcm_t* handle, | 45 MOCK_METHOD3(PcmWritei, |
| 48 const void* buffer, | 46 snd_pcm_sframes_t(snd_pcm_t* handle, const void* buffer, |
| 49 snd_pcm_uframes_t size)); | 47 snd_pcm_uframes_t size)); |
| 50 MOCK_METHOD3(PcmReadi, snd_pcm_sframes_t(snd_pcm_t* handle, | 48 MOCK_METHOD3(PcmReadi, snd_pcm_sframes_t(snd_pcm_t* handle, void* buffer, |
| 51 void* buffer, | |
| 52 snd_pcm_uframes_t size)); | 49 snd_pcm_uframes_t size)); |
| 53 MOCK_METHOD3(PcmRecover, int(snd_pcm_t* handle, int err, int silent)); | 50 MOCK_METHOD3(PcmRecover, int(snd_pcm_t* handle, int err, int silent)); |
| 54 MOCK_METHOD7(PcmSetParams, int(snd_pcm_t* handle, snd_pcm_format_t format, | 51 MOCK_METHOD7(PcmSetParams, |
| 55 snd_pcm_access_t access, unsigned int channels, | 52 int(snd_pcm_t* handle, snd_pcm_format_t format, |
| 56 unsigned int rate, int soft_resample, | 53 snd_pcm_access_t access, unsigned int channels, |
| 57 unsigned int latency)); | 54 unsigned int rate, int soft_resample, unsigned int latency)); |
| 58 MOCK_METHOD3(PcmGetParams, int(snd_pcm_t* handle, | 55 MOCK_METHOD3(PcmGetParams, |
| 59 snd_pcm_uframes_t* buffer_size, | 56 int(snd_pcm_t* handle, snd_pcm_uframes_t* buffer_size, |
| 60 snd_pcm_uframes_t* period_size)); | 57 snd_pcm_uframes_t* period_size)); |
| 61 MOCK_METHOD1(PcmName, const char*(snd_pcm_t* handle)); | 58 MOCK_METHOD1(PcmName, const char*(snd_pcm_t* handle)); |
| 62 MOCK_METHOD1(PcmAvailUpdate, snd_pcm_sframes_t(snd_pcm_t* handle)); | 59 MOCK_METHOD1(PcmAvailUpdate, snd_pcm_sframes_t(snd_pcm_t* handle)); |
| 63 MOCK_METHOD1(PcmState, snd_pcm_state_t(snd_pcm_t* handle)); | 60 MOCK_METHOD1(PcmState, snd_pcm_state_t(snd_pcm_t* handle)); |
| 64 MOCK_METHOD1(PcmStart, int(snd_pcm_t* handle)); | 61 MOCK_METHOD1(PcmStart, int(snd_pcm_t* handle)); |
| 65 | 62 |
| 66 MOCK_METHOD1(StrError, const char*(int errnum)); | 63 MOCK_METHOD1(StrError, const char*(int errnum)); |
| 67 }; | 64 }; |
| 68 | 65 |
| 69 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { | 66 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { |
| 70 public: | 67 public: |
| 71 MOCK_METHOD2(OnMoreData, int(AudioBus* audio_bus, | 68 MOCK_METHOD2(OnMoreData, |
| 72 AudioBuffersState buffers_state)); | 69 int(AudioBus* audio_bus, AudioBuffersState buffers_state)); |
| 73 MOCK_METHOD3(OnMoreIOData, int(AudioBus* source, | 70 MOCK_METHOD3(OnMoreIOData, int(AudioBus* source, AudioBus* dest, |
| 74 AudioBus* dest, | |
| 75 AudioBuffersState buffers_state)); | 71 AudioBuffersState buffers_state)); |
| 76 MOCK_METHOD1(OnError, void(AudioOutputStream* stream)); | 72 MOCK_METHOD1(OnError, void(AudioOutputStream* stream)); |
| 77 }; | 73 }; |
| 78 | 74 |
| 79 class MockAudioManagerLinux : public AudioManagerLinux { | 75 class MockAudioManagerLinux : public AudioManagerLinux { |
| 80 public: | 76 public: |
| 81 MOCK_METHOD0(Init, void()); | 77 MOCK_METHOD0(Init, void()); |
| 82 MOCK_METHOD0(HasAudioOutputDevices, bool()); | 78 MOCK_METHOD0(HasAudioOutputDevices, bool()); |
| 83 MOCK_METHOD0(HasAudioInputDevices, bool()); | 79 MOCK_METHOD0(HasAudioInputDevices, bool()); |
| 84 MOCK_METHOD1(MakeLinearOutputStream, AudioOutputStream*( | 80 MOCK_METHOD1(MakeLinearOutputStream, |
| 85 const AudioParameters& params)); | 81 AudioOutputStream*(const AudioParameters& params)); |
| 86 MOCK_METHOD2(MakeLowLatencyOutputStream, AudioOutputStream*( | 82 MOCK_METHOD2(MakeLowLatencyOutputStream, |
| 87 const AudioParameters& params, const std::string& input_device_id)); | 83 AudioOutputStream*(const AudioParameters& params, |
| 88 MOCK_METHOD2(MakeLowLatencyInputStream, AudioInputStream*( | 84 const std::string& input_device_id)); |
| 89 const AudioParameters& params, const std::string& device_id)); | 85 MOCK_METHOD2(MakeLowLatencyInputStream, |
| 86 AudioInputStream*(const AudioParameters& params, |
| 87 const std::string& device_id)); |
| 90 | 88 |
| 91 // We need to override this function in order to skip the checking the number | 89 // We need to override this function in order to skip the checking the number |
| 92 // of active output streams. It is because the number of active streams | 90 // of active output streams. It is because the number of active streams |
| 93 // is managed inside MakeAudioOutputStream, and we don't use | 91 // is managed inside MakeAudioOutputStream, and we don't use |
| 94 // MakeAudioOutputStream to create the stream in the tests. | 92 // MakeAudioOutputStream to create the stream in the tests. |
| 95 virtual void ReleaseOutputStream(AudioOutputStream* stream) OVERRIDE { | 93 virtual void ReleaseOutputStream(AudioOutputStream* stream) OVERRIDE { |
| 96 DCHECK(stream); | 94 DCHECK(stream); |
| 97 delete stream; | 95 delete stream; |
| 98 } | 96 } |
| 99 | 97 |
| 100 // We don't mock this method since all tests will do the same thing | 98 // We don't mock this method since all tests will do the same thing |
| 101 // and use the current message loop. | 99 // and use the current message loop. |
| 102 virtual scoped_refptr<base::MessageLoopProxy> GetMessageLoop() OVERRIDE { | 100 virtual scoped_refptr<base::MessageLoopProxy> GetMessageLoop() OVERRIDE { |
| 103 return base::MessageLoop::current()->message_loop_proxy(); | 101 return base::MessageLoop::current()->message_loop_proxy(); |
| 104 } | 102 } |
| 105 }; | 103 }; |
| 106 | 104 |
| 107 class AlsaPcmOutputStreamTest : public testing::Test { | 105 class AlsaPcmOutputStreamTest : public testing::Test { |
| 108 protected: | 106 protected: |
| 109 AlsaPcmOutputStreamTest() { | 107 AlsaPcmOutputStreamTest() { |
| 110 mock_manager_.reset(new StrictMock<MockAudioManagerLinux>()); | 108 mock_manager_.reset(new StrictMock<MockAudioManagerLinux>()); |
| 111 } | 109 } |
| 112 | 110 |
| 113 virtual ~AlsaPcmOutputStreamTest() { | 111 virtual ~AlsaPcmOutputStreamTest() {} |
| 114 } | |
| 115 | 112 |
| 116 AlsaPcmOutputStream* CreateStream(ChannelLayout layout) { | 113 AlsaPcmOutputStream* CreateStream(ChannelLayout layout) { |
| 117 return CreateStream(layout, kTestFramesPerPacket); | 114 return CreateStream(layout, kTestFramesPerPacket); |
| 118 } | 115 } |
| 119 | 116 |
| 120 AlsaPcmOutputStream* CreateStream(ChannelLayout layout, | 117 AlsaPcmOutputStream* CreateStream(ChannelLayout layout, |
| 121 int32 samples_per_packet) { | 118 int32 samples_per_packet) { |
| 122 AudioParameters params(kTestFormat, layout, kTestSampleRate, | 119 AudioParameters params(kTestFormat, layout, kTestSampleRate, |
| 123 kTestBitsPerSample, samples_per_packet); | 120 kTestBitsPerSample, samples_per_packet); |
| 124 return new AlsaPcmOutputStream(kTestDeviceName, | 121 return new AlsaPcmOutputStream(kTestDeviceName, params, &mock_alsa_wrapper_, |
| 125 params, | |
| 126 &mock_alsa_wrapper_, | |
| 127 mock_manager_.get()); | 122 mock_manager_.get()); |
| 128 } | 123 } |
| 129 | 124 |
| 130 // Helper function to malloc the string returned by DeviceNameHint for NAME. | 125 // Helper function to malloc the string returned by DeviceNameHint for NAME. |
| 131 static char* EchoHint(const void* name, Unused) { | 126 static char* EchoHint(const void* name, Unused) { |
| 132 return strdup(static_cast<const char*>(name)); | 127 return strdup(static_cast<const char*>(name)); |
| 133 } | 128 } |
| 134 | 129 |
| 135 // Helper function to malloc the string returned by DeviceNameHint for IOID. | 130 // Helper function to malloc the string returned by DeviceNameHint for IOID. |
| 136 static char* OutputHint(Unused, Unused) { | 131 static char* OutputHint(Unused, Unused) { return strdup("Output"); } |
| 137 return strdup("Output"); | |
| 138 } | |
| 139 | 132 |
| 140 // Helper function to initialize |test_stream->buffer_|. Must be called | 133 // Helper function to initialize |test_stream->buffer_|. Must be called |
| 141 // in all tests that use buffer_ without opening the stream. | 134 // in all tests that use buffer_ without opening the stream. |
| 142 void InitBuffer(AlsaPcmOutputStream* test_stream) { | 135 void InitBuffer(AlsaPcmOutputStream* test_stream) { |
| 143 DCHECK(test_stream); | 136 DCHECK(test_stream); |
| 144 packet_ = new media::DataBuffer(kTestPacketSize); | 137 packet_ = new media::DataBuffer(kTestPacketSize); |
| 145 packet_->SetDataSize(kTestPacketSize); | 138 packet_->set_data_size(kTestPacketSize); |
| 146 test_stream->buffer_.reset(new media::SeekableBuffer(0, kTestPacketSize)); | 139 test_stream->buffer_.reset(new media::SeekableBuffer(0, kTestPacketSize)); |
| 147 test_stream->buffer_->Append(packet_.get()); | 140 test_stream->buffer_->Append(packet_.get()); |
| 148 } | 141 } |
| 149 | 142 |
| 150 static const ChannelLayout kTestChannelLayout; | 143 static const ChannelLayout kTestChannelLayout; |
| 151 static const int kTestSampleRate; | 144 static const int kTestSampleRate; |
| 152 static const int kTestBitsPerSample; | 145 static const int kTestBitsPerSample; |
| 153 static const int kTestBytesPerFrame; | 146 static const int kTestBytesPerFrame; |
| 154 static const AudioParameters::Format kTestFormat; | 147 static const AudioParameters::Format kTestFormat; |
| 155 static const char kTestDeviceName[]; | 148 static const char kTestDeviceName[]; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 const int AlsaPcmOutputStreamTest::kTestFailedErrno = -EACCES; | 189 const int AlsaPcmOutputStreamTest::kTestFailedErrno = -EACCES; |
| 197 snd_pcm_t* const AlsaPcmOutputStreamTest::kFakeHandle = | 190 snd_pcm_t* const AlsaPcmOutputStreamTest::kFakeHandle = |
| 198 reinterpret_cast<snd_pcm_t*>(1); | 191 reinterpret_cast<snd_pcm_t*>(1); |
| 199 | 192 |
| 200 char AlsaPcmOutputStreamTest::kSurround40[] = "surround40:CARD=foo,DEV=0"; | 193 char AlsaPcmOutputStreamTest::kSurround40[] = "surround40:CARD=foo,DEV=0"; |
| 201 char AlsaPcmOutputStreamTest::kSurround41[] = "surround41:CARD=foo,DEV=0"; | 194 char AlsaPcmOutputStreamTest::kSurround41[] = "surround41:CARD=foo,DEV=0"; |
| 202 char AlsaPcmOutputStreamTest::kSurround50[] = "surround50:CARD=foo,DEV=0"; | 195 char AlsaPcmOutputStreamTest::kSurround50[] = "surround50:CARD=foo,DEV=0"; |
| 203 char AlsaPcmOutputStreamTest::kSurround51[] = "surround51:CARD=foo,DEV=0"; | 196 char AlsaPcmOutputStreamTest::kSurround51[] = "surround51:CARD=foo,DEV=0"; |
| 204 char AlsaPcmOutputStreamTest::kSurround70[] = "surround70:CARD=foo,DEV=0"; | 197 char AlsaPcmOutputStreamTest::kSurround70[] = "surround70:CARD=foo,DEV=0"; |
| 205 char AlsaPcmOutputStreamTest::kSurround71[] = "surround71:CARD=foo,DEV=0"; | 198 char AlsaPcmOutputStreamTest::kSurround71[] = "surround71:CARD=foo,DEV=0"; |
| 206 void* AlsaPcmOutputStreamTest::kFakeHints[] = { | 199 void* AlsaPcmOutputStreamTest::kFakeHints[] = {kSurround40, kSurround41, |
| 207 kSurround40, kSurround41, kSurround50, kSurround51, | 200 kSurround50, kSurround51, |
| 208 kSurround70, kSurround71, NULL }; | 201 kSurround70, kSurround71, NULL}; |
| 209 | 202 |
| 210 // Custom action to clear a memory buffer. | 203 // Custom action to clear a memory buffer. |
| 211 ACTION(ClearBuffer) { | 204 ACTION(ClearBuffer) { arg0->Zero(); } |
| 212 arg0->Zero(); | |
| 213 } | |
| 214 | 205 |
| 215 TEST_F(AlsaPcmOutputStreamTest, ConstructedState) { | 206 TEST_F(AlsaPcmOutputStreamTest, ConstructedState) { |
| 216 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 207 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 217 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream->state()); | 208 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream->state()); |
| 218 test_stream->Close(); | 209 test_stream->Close(); |
| 219 | 210 |
| 220 // Should support mono. | 211 // Should support mono. |
| 221 test_stream = CreateStream(CHANNEL_LAYOUT_MONO); | 212 test_stream = CreateStream(CHANNEL_LAYOUT_MONO); |
| 222 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream->state()); | 213 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream->state()); |
| 223 test_stream->Close(); | 214 test_stream->Close(); |
| 224 | 215 |
| 225 // Should support multi-channel. | 216 // Should support multi-channel. |
| 226 test_stream = CreateStream(CHANNEL_LAYOUT_SURROUND); | 217 test_stream = CreateStream(CHANNEL_LAYOUT_SURROUND); |
| 227 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream->state()); | 218 EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream->state()); |
| 228 test_stream->Close(); | 219 test_stream->Close(); |
| 229 | 220 |
| 230 // Bad bits per sample. | 221 // Bad bits per sample. |
| 231 AudioParameters bad_bps_params(kTestFormat, kTestChannelLayout, | 222 AudioParameters bad_bps_params(kTestFormat, kTestChannelLayout, |
| 232 kTestSampleRate, kTestBitsPerSample - 1, | 223 kTestSampleRate, kTestBitsPerSample - 1, |
| 233 kTestFramesPerPacket); | 224 kTestFramesPerPacket); |
| 234 test_stream = new AlsaPcmOutputStream(kTestDeviceName, | 225 test_stream = |
| 235 bad_bps_params, | 226 new AlsaPcmOutputStream(kTestDeviceName, bad_bps_params, |
| 236 &mock_alsa_wrapper_, | 227 &mock_alsa_wrapper_, mock_manager_.get()); |
| 237 mock_manager_.get()); | |
| 238 EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream->state()); | 228 EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream->state()); |
| 239 test_stream->Close(); | 229 test_stream->Close(); |
| 240 | 230 |
| 241 // Bad format. | 231 // Bad format. |
| 242 AudioParameters bad_format_params( | 232 AudioParameters bad_format_params(AudioParameters::AUDIO_LAST_FORMAT, |
| 243 AudioParameters::AUDIO_LAST_FORMAT, kTestChannelLayout, kTestSampleRate, | 233 kTestChannelLayout, kTestSampleRate, |
| 244 kTestBitsPerSample, kTestFramesPerPacket); | 234 kTestBitsPerSample, kTestFramesPerPacket); |
| 245 test_stream = new AlsaPcmOutputStream(kTestDeviceName, | 235 test_stream = |
| 246 bad_format_params, | 236 new AlsaPcmOutputStream(kTestDeviceName, bad_format_params, |
| 247 &mock_alsa_wrapper_, | 237 &mock_alsa_wrapper_, mock_manager_.get()); |
| 248 mock_manager_.get()); | |
| 249 EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream->state()); | 238 EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream->state()); |
| 250 test_stream->Close(); | 239 test_stream->Close(); |
| 251 } | 240 } |
| 252 | 241 |
| 253 TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) { | 242 TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) { |
| 254 const double kMicrosPerFrame = | 243 const double kMicrosPerFrame = static_cast<double>(1000000) / kTestSampleRate; |
| 255 static_cast<double>(1000000) / kTestSampleRate; | |
| 256 const double kPacketFramesInMinLatency = | 244 const double kPacketFramesInMinLatency = |
| 257 AlsaPcmOutputStream::kMinLatencyMicros / kMicrosPerFrame / 2.0; | 245 AlsaPcmOutputStream::kMinLatencyMicros / kMicrosPerFrame / 2.0; |
| 258 | 246 |
| 259 // Test that packets which would cause a latency under less than | 247 // Test that packets which would cause a latency under less than |
| 260 // AlsaPcmOutputStream::kMinLatencyMicros will get clipped to | 248 // AlsaPcmOutputStream::kMinLatencyMicros will get clipped to |
| 261 // AlsaPcmOutputStream::kMinLatencyMicros, | 249 // AlsaPcmOutputStream::kMinLatencyMicros, |
| 262 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 250 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
| 263 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), | 251 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); |
| 264 Return(0))); | 252 EXPECT_CALL( |
| 265 EXPECT_CALL(mock_alsa_wrapper_, | 253 mock_alsa_wrapper_, |
| 266 PcmSetParams(_, _, _, _, _, _, | 254 PcmSetParams(_, _, _, _, _, _, AlsaPcmOutputStream::kMinLatencyMicros)) |
| 267 AlsaPcmOutputStream::kMinLatencyMicros)) | |
| 268 .WillOnce(Return(0)); | 255 .WillOnce(Return(0)); |
| 269 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) | 256 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)).WillOnce( |
| 270 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), | 257 DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), |
| 271 SetArgumentPointee<2>(kTestFramesPerPacket / 2), | 258 SetArgumentPointee<2>(kTestFramesPerPacket / 2), Return(0))); |
| 272 Return(0))); | |
| 273 | 259 |
| 274 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout, | 260 AlsaPcmOutputStream* test_stream = |
| 275 kPacketFramesInMinLatency); | 261 CreateStream(kTestChannelLayout, kPacketFramesInMinLatency); |
| 276 ASSERT_TRUE(test_stream->Open()); | 262 ASSERT_TRUE(test_stream->Open()); |
| 277 | 263 |
| 278 // Now close it and test that everything was released. | 264 // Now close it and test that everything was released. |
| 279 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)).WillOnce(Return(0)); | 265 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)).WillOnce(Return(0)); |
| 280 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 266 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
| 281 .WillOnce(Return(kTestDeviceName)); | 267 .WillOnce(Return(kTestDeviceName)); |
| 282 test_stream->Close(); | 268 test_stream->Close(); |
| 283 | 269 |
| 284 Mock::VerifyAndClear(&mock_alsa_wrapper_); | 270 Mock::VerifyAndClear(&mock_alsa_wrapper_); |
| 285 Mock::VerifyAndClear(mock_manager_.get()); | 271 Mock::VerifyAndClear(mock_manager_.get()); |
| 286 | 272 |
| 287 // Test that having more packets ends up with a latency based on packet size. | 273 // Test that having more packets ends up with a latency based on packet size. |
| 288 const int kOverMinLatencyPacketSize = kPacketFramesInMinLatency + 1; | 274 const int kOverMinLatencyPacketSize = kPacketFramesInMinLatency + 1; |
| 289 int64 expected_micros = AlsaPcmOutputStream::FramesToTimeDelta( | 275 int64 expected_micros = AlsaPcmOutputStream::FramesToTimeDelta( |
| 290 kOverMinLatencyPacketSize * 2, kTestSampleRate).InMicroseconds(); | 276 kOverMinLatencyPacketSize * 2, kTestSampleRate).InMicroseconds(); |
| 291 | 277 |
| 292 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 278 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
| 293 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); | 279 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); |
| 294 EXPECT_CALL(mock_alsa_wrapper_, | 280 EXPECT_CALL(mock_alsa_wrapper_, |
| 295 PcmSetParams(_, _, _, _, _, _, expected_micros)) | 281 PcmSetParams(_, _, _, _, _, _, expected_micros)) |
| 296 .WillOnce(Return(0)); | 282 .WillOnce(Return(0)); |
| 297 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) | 283 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)).WillOnce( |
| 298 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), | 284 DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), |
| 299 SetArgumentPointee<2>(kTestFramesPerPacket / 2), | 285 SetArgumentPointee<2>(kTestFramesPerPacket / 2), Return(0))); |
| 300 Return(0))); | |
| 301 | 286 |
| 302 test_stream = CreateStream(kTestChannelLayout, | 287 test_stream = CreateStream(kTestChannelLayout, kOverMinLatencyPacketSize); |
| 303 kOverMinLatencyPacketSize); | |
| 304 ASSERT_TRUE(test_stream->Open()); | 288 ASSERT_TRUE(test_stream->Open()); |
| 305 | 289 |
| 306 // Now close it and test that everything was released. | 290 // Now close it and test that everything was released. |
| 307 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) | 291 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)).WillOnce(Return(0)); |
| 308 .WillOnce(Return(0)); | |
| 309 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 292 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
| 310 .WillOnce(Return(kTestDeviceName)); | 293 .WillOnce(Return(kTestDeviceName)); |
| 311 test_stream->Close(); | 294 test_stream->Close(); |
| 312 | 295 |
| 313 Mock::VerifyAndClear(&mock_alsa_wrapper_); | 296 Mock::VerifyAndClear(&mock_alsa_wrapper_); |
| 314 Mock::VerifyAndClear(mock_manager_.get()); | 297 Mock::VerifyAndClear(mock_manager_.get()); |
| 315 } | 298 } |
| 316 | 299 |
| 317 TEST_F(AlsaPcmOutputStreamTest, OpenClose) { | 300 TEST_F(AlsaPcmOutputStreamTest, OpenClose) { |
| 318 int64 expected_micros = AlsaPcmOutputStream::FramesToTimeDelta( | 301 int64 expected_micros = AlsaPcmOutputStream::FramesToTimeDelta( |
| 319 2 * kTestFramesPerPacket, kTestSampleRate).InMicroseconds(); | 302 2 * kTestFramesPerPacket, kTestSampleRate).InMicroseconds(); |
| 320 | 303 |
| 321 // Open() call opens the playback device, sets the parameters, posts a task | 304 // Open() call opens the playback device, sets the parameters, posts a task |
| 322 // with the resulting configuration data, and transitions the object state to | 305 // with the resulting configuration data, and transitions the object state to |
| 323 // kIsOpened. | 306 // kIsOpened. |
| 324 EXPECT_CALL(mock_alsa_wrapper_, | 307 EXPECT_CALL(mock_alsa_wrapper_, |
| 325 PcmOpen(_, StrEq(kTestDeviceName), | 308 PcmOpen(_, StrEq(kTestDeviceName), SND_PCM_STREAM_PLAYBACK, |
| 326 SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) | 309 SND_PCM_NONBLOCK)) |
| 327 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), | 310 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); |
| 328 Return(0))); | |
| 329 EXPECT_CALL(mock_alsa_wrapper_, | 311 EXPECT_CALL(mock_alsa_wrapper_, |
| 330 PcmSetParams(kFakeHandle, | 312 PcmSetParams( |
| 331 SND_PCM_FORMAT_U8, | 313 kFakeHandle, SND_PCM_FORMAT_U8, SND_PCM_ACCESS_RW_INTERLEAVED, |
| 332 SND_PCM_ACCESS_RW_INTERLEAVED, | 314 ChannelLayoutToChannelCount(kTestChannelLayout), |
| 333 ChannelLayoutToChannelCount(kTestChannelLayout), | 315 kTestSampleRate, 1, expected_micros)).WillOnce(Return(0)); |
| 334 kTestSampleRate, | 316 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(kFakeHandle, _, _)).WillOnce( |
| 335 1, | 317 DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), |
| 336 expected_micros)) | 318 SetArgumentPointee<2>(kTestFramesPerPacket / 2), Return(0))); |
| 337 .WillOnce(Return(0)); | |
| 338 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(kFakeHandle, _, _)) | |
| 339 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), | |
| 340 SetArgumentPointee<2>(kTestFramesPerPacket / 2), | |
| 341 Return(0))); | |
| 342 | 319 |
| 343 // Open the stream. | 320 // Open the stream. |
| 344 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 321 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 345 ASSERT_TRUE(test_stream->Open()); | 322 ASSERT_TRUE(test_stream->Open()); |
| 346 | 323 |
| 347 EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream->state()); | 324 EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream->state()); |
| 348 EXPECT_EQ(kFakeHandle, test_stream->playback_handle_); | 325 EXPECT_EQ(kFakeHandle, test_stream->playback_handle_); |
| 349 EXPECT_EQ(kTestFramesPerPacket, test_stream->frames_per_packet_); | 326 EXPECT_EQ(kTestFramesPerPacket, test_stream->frames_per_packet_); |
| 350 EXPECT_TRUE(test_stream->buffer_.get()); | 327 EXPECT_TRUE(test_stream->buffer_.get()); |
| 351 EXPECT_FALSE(test_stream->stop_stream_); | 328 EXPECT_FALSE(test_stream->stop_stream_); |
| 352 | 329 |
| 353 // Now close it and test that everything was released. | 330 // Now close it and test that everything was released. |
| 354 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) | 331 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)).WillOnce(Return(0)); |
| 355 .WillOnce(Return(0)); | |
| 356 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 332 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
| 357 .WillOnce(Return(kTestDeviceName)); | 333 .WillOnce(Return(kTestDeviceName)); |
| 358 test_stream->Close(); | 334 test_stream->Close(); |
| 359 } | 335 } |
| 360 | 336 |
| 361 TEST_F(AlsaPcmOutputStreamTest, PcmOpenFailed) { | 337 TEST_F(AlsaPcmOutputStreamTest, PcmOpenFailed) { |
| 362 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 338 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
| 363 .WillOnce(Return(kTestFailedErrno)); | 339 .WillOnce(Return(kTestFailedErrno)); |
| 364 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) | 340 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) |
| 365 .WillOnce(Return(kDummyMessage)); | 341 .WillOnce(Return(kDummyMessage)); |
| 366 | 342 |
| 367 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 343 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 368 ASSERT_FALSE(test_stream->Open()); | 344 ASSERT_FALSE(test_stream->Open()); |
| 369 ASSERT_EQ(AlsaPcmOutputStream::kInError, test_stream->state()); | 345 ASSERT_EQ(AlsaPcmOutputStream::kInError, test_stream->state()); |
| 370 | 346 |
| 371 // Ensure internal state is set for a no-op stream if PcmOpen() failes. | 347 // Ensure internal state is set for a no-op stream if PcmOpen() failes. |
| 372 EXPECT_TRUE(test_stream->stop_stream_); | 348 EXPECT_TRUE(test_stream->stop_stream_); |
| 373 EXPECT_TRUE(test_stream->playback_handle_ == NULL); | 349 EXPECT_TRUE(test_stream->playback_handle_ == NULL); |
| 374 EXPECT_FALSE(test_stream->buffer_.get()); | 350 EXPECT_FALSE(test_stream->buffer_.get()); |
| 375 | 351 |
| 376 // Close the stream since we opened it to make destruction happy. | 352 // Close the stream since we opened it to make destruction happy. |
| 377 test_stream->Close(); | 353 test_stream->Close(); |
| 378 } | 354 } |
| 379 | 355 |
| 380 TEST_F(AlsaPcmOutputStreamTest, PcmSetParamsFailed) { | 356 TEST_F(AlsaPcmOutputStreamTest, PcmSetParamsFailed) { |
| 381 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 357 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
| 382 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), | 358 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); |
| 383 Return(0))); | |
| 384 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) | 359 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) |
| 385 .WillOnce(Return(kTestFailedErrno)); | 360 .WillOnce(Return(kTestFailedErrno)); |
| 386 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) | 361 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)).WillOnce(Return(0)); |
| 387 .WillOnce(Return(0)); | |
| 388 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 362 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
| 389 .WillOnce(Return(kTestDeviceName)); | 363 .WillOnce(Return(kTestDeviceName)); |
| 390 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) | 364 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) |
| 391 .WillOnce(Return(kDummyMessage)); | 365 .WillOnce(Return(kDummyMessage)); |
| 392 | 366 |
| 393 // If open fails, the stream stays in kCreated because it has effectively had | 367 // If open fails, the stream stays in kCreated because it has effectively had |
| 394 // no changes. | 368 // no changes. |
| 395 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 369 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 396 ASSERT_FALSE(test_stream->Open()); | 370 ASSERT_FALSE(test_stream->Open()); |
| 397 EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream->state()); | 371 EXPECT_EQ(AlsaPcmOutputStream::kInError, test_stream->state()); |
| 398 | 372 |
| 399 // Ensure internal state is set for a no-op stream if PcmSetParams() failes. | 373 // Ensure internal state is set for a no-op stream if PcmSetParams() failes. |
| 400 EXPECT_TRUE(test_stream->stop_stream_); | 374 EXPECT_TRUE(test_stream->stop_stream_); |
| 401 EXPECT_TRUE(test_stream->playback_handle_ == NULL); | 375 EXPECT_TRUE(test_stream->playback_handle_ == NULL); |
| 402 EXPECT_FALSE(test_stream->buffer_.get()); | 376 EXPECT_FALSE(test_stream->buffer_.get()); |
| 403 | 377 |
| 404 // Close the stream since we opened it to make destruction happy. | 378 // Close the stream since we opened it to make destruction happy. |
| 405 test_stream->Close(); | 379 test_stream->Close(); |
| 406 } | 380 } |
| 407 | 381 |
| 408 TEST_F(AlsaPcmOutputStreamTest, StartStop) { | 382 TEST_F(AlsaPcmOutputStreamTest, StartStop) { |
| 409 // Open() call opens the playback device, sets the parameters, posts a task | 383 // Open() call opens the playback device, sets the parameters, posts a task |
| 410 // with the resulting configuration data, and transitions the object state to | 384 // with the resulting configuration data, and transitions the object state to |
| 411 // kIsOpened. | 385 // kIsOpened. |
| 412 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 386 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
| 413 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), | 387 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); |
| 414 Return(0))); | |
| 415 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) | 388 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) |
| 416 .WillOnce(Return(0)); | 389 .WillOnce(Return(0)); |
| 417 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) | 390 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)).WillOnce( |
| 418 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), | 391 DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), |
| 419 SetArgumentPointee<2>(kTestFramesPerPacket / 2), | 392 SetArgumentPointee<2>(kTestFramesPerPacket / 2), Return(0))); |
| 420 Return(0))); | |
| 421 | 393 |
| 422 // Open the stream. | 394 // Open the stream. |
| 423 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 395 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 424 ASSERT_TRUE(test_stream->Open()); | 396 ASSERT_TRUE(test_stream->Open()); |
| 425 | 397 |
| 426 // Expect Device setup. | 398 // Expect Device setup. |
| 427 EXPECT_CALL(mock_alsa_wrapper_, PcmDrop(kFakeHandle)) | 399 EXPECT_CALL(mock_alsa_wrapper_, PcmDrop(kFakeHandle)).WillOnce(Return(0)); |
| 428 .WillOnce(Return(0)); | 400 EXPECT_CALL(mock_alsa_wrapper_, PcmPrepare(kFakeHandle)).WillOnce(Return(0)); |
| 429 EXPECT_CALL(mock_alsa_wrapper_, PcmPrepare(kFakeHandle)) | |
| 430 .WillOnce(Return(0)); | |
| 431 | 401 |
| 432 // Expect the pre-roll. | 402 // Expect the pre-roll. |
| 433 MockAudioSourceCallback mock_callback; | 403 MockAudioSourceCallback mock_callback; |
| 434 EXPECT_CALL(mock_alsa_wrapper_, PcmState(kFakeHandle)) | 404 EXPECT_CALL(mock_alsa_wrapper_, PcmState(kFakeHandle)) |
| 435 .WillRepeatedly(Return(SND_PCM_STATE_RUNNING)); | 405 .WillRepeatedly(Return(SND_PCM_STATE_RUNNING)); |
| 436 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(kFakeHandle, _)) | 406 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(kFakeHandle, _)) |
| 437 .WillRepeatedly(DoAll(SetArgumentPointee<1>(0), Return(0))); | 407 .WillRepeatedly(DoAll(SetArgumentPointee<1>(0), Return(0))); |
| 438 EXPECT_CALL(mock_callback, OnMoreData(_, _)) | 408 EXPECT_CALL(mock_callback, OnMoreData(_, _)) |
| 439 .WillRepeatedly(DoAll(ClearBuffer(), Return(kTestFramesPerPacket))); | 409 .WillRepeatedly(DoAll(ClearBuffer(), Return(kTestFramesPerPacket))); |
| 440 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) | 410 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) |
| 441 .WillRepeatedly(Return(kTestFramesPerPacket)); | 411 .WillRepeatedly(Return(kTestFramesPerPacket)); |
| 442 | 412 |
| 443 // Expect scheduling. | 413 // Expect scheduling. |
| 444 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) | 414 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)).Times(AtLeast(2)) |
| 445 .Times(AtLeast(2)) | |
| 446 .WillRepeatedly(Return(kTestFramesPerPacket)); | 415 .WillRepeatedly(Return(kTestFramesPerPacket)); |
| 447 | 416 |
| 448 test_stream->Start(&mock_callback); | 417 test_stream->Start(&mock_callback); |
| 449 // Start() will issue a WriteTask() directly and then schedule the next one, | 418 // Start() will issue a WriteTask() directly and then schedule the next one, |
| 450 // call Stop() immediately after to ensure we don't run the message loop | 419 // call Stop() immediately after to ensure we don't run the message loop |
| 451 // forever. | 420 // forever. |
| 452 test_stream->Stop(); | 421 test_stream->Stop(); |
| 453 message_loop_.RunUntilIdle(); | 422 message_loop_.RunUntilIdle(); |
| 454 | 423 |
| 455 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) | 424 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)).WillOnce(Return(0)); |
| 456 .WillOnce(Return(0)); | |
| 457 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 425 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
| 458 .WillOnce(Return(kTestDeviceName)); | 426 .WillOnce(Return(kTestDeviceName)); |
| 459 test_stream->Close(); | 427 test_stream->Close(); |
| 460 } | 428 } |
| 461 | 429 |
| 462 TEST_F(AlsaPcmOutputStreamTest, WritePacket_FinishedPacket) { | 430 TEST_F(AlsaPcmOutputStreamTest, WritePacket_FinishedPacket) { |
| 463 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 431 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 464 InitBuffer(test_stream); | 432 InitBuffer(test_stream); |
| 465 test_stream->TransitionTo(AlsaPcmOutputStream::kIsOpened); | 433 test_stream->TransitionTo(AlsaPcmOutputStream::kIsOpened); |
| 466 test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying); | 434 test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying); |
| 467 | 435 |
| 468 // Nothing should happen. Don't set any expectations and Our strict mocks | 436 // Nothing should happen. Don't set any expectations and Our strict mocks |
| 469 // should verify most of this. | 437 // should verify most of this. |
| 470 | 438 |
| 471 // Test empty buffer. | 439 // Test empty buffer. |
| 472 test_stream->buffer_->Clear(); | 440 test_stream->buffer_->Clear(); |
| 473 test_stream->WritePacket(); | 441 test_stream->WritePacket(); |
| 474 test_stream->Close(); | 442 test_stream->Close(); |
| 475 } | 443 } |
| 476 | 444 |
| 477 TEST_F(AlsaPcmOutputStreamTest, WritePacket_NormalPacket) { | 445 TEST_F(AlsaPcmOutputStreamTest, WritePacket_NormalPacket) { |
| 478 // We need to open the stream before writing data to ALSA. | 446 // We need to open the stream before writing data to ALSA. |
| 479 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 447 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
| 480 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), | 448 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); |
| 481 Return(0))); | |
| 482 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) | 449 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) |
| 483 .WillOnce(Return(0)); | 450 .WillOnce(Return(0)); |
| 484 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) | 451 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)).WillOnce( |
| 485 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), | 452 DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), |
| 486 SetArgumentPointee<2>(kTestFramesPerPacket / 2), | 453 SetArgumentPointee<2>(kTestFramesPerPacket / 2), Return(0))); |
| 487 Return(0))); | |
| 488 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 454 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 489 ASSERT_TRUE(test_stream->Open()); | 455 ASSERT_TRUE(test_stream->Open()); |
| 490 InitBuffer(test_stream); | 456 InitBuffer(test_stream); |
| 491 test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying); | 457 test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying); |
| 492 | 458 |
| 493 // Write a little less than half the data. | 459 // Write a little less than half the data. |
| 494 int written = packet_->GetDataSize() / kTestBytesPerFrame / 2 - 1; | 460 int written = packet_->get_data_size() / kTestBytesPerFrame / 2 - 1; |
| 495 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) | 461 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) |
| 496 .WillOnce(Return(written)); | |
| 497 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, packet_->GetData(), _)) | |
| 498 .WillOnce(Return(written)); | 462 .WillOnce(Return(written)); |
| 463 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, packet_->get_data(), |
| 464 _)).WillOnce(Return(written)); |
| 499 | 465 |
| 500 test_stream->WritePacket(); | 466 test_stream->WritePacket(); |
| 501 | 467 |
| 502 ASSERT_EQ(test_stream->buffer_->forward_bytes(), | 468 ASSERT_EQ(test_stream->buffer_->forward_bytes(), |
| 503 packet_->GetDataSize() - written * kTestBytesPerFrame); | 469 packet_->get_data_size() - written * kTestBytesPerFrame); |
| 504 | 470 |
| 505 // Write the rest. | 471 // Write the rest. |
| 506 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) | 472 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) |
| 507 .WillOnce(Return(kTestFramesPerPacket - written)); | 473 .WillOnce(Return(kTestFramesPerPacket - written)); |
| 508 EXPECT_CALL(mock_alsa_wrapper_, | 474 EXPECT_CALL(mock_alsa_wrapper_, |
| 509 PcmWritei(kFakeHandle, | 475 PcmWritei(kFakeHandle, |
| 510 packet_->GetData() + written * kTestBytesPerFrame, | 476 packet_->get_data() + written * kTestBytesPerFrame, _)) |
| 511 _)) | 477 .WillOnce( |
| 512 .WillOnce(Return(packet_->GetDataSize() / kTestBytesPerFrame - written)); | 478 Return(packet_->get_data_size() / kTestBytesPerFrame - written)); |
| 513 test_stream->WritePacket(); | 479 test_stream->WritePacket(); |
| 514 EXPECT_EQ(0, test_stream->buffer_->forward_bytes()); | 480 EXPECT_EQ(0, test_stream->buffer_->forward_bytes()); |
| 515 | 481 |
| 516 // Now close it and test that everything was released. | 482 // Now close it and test that everything was released. |
| 517 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) | 483 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)).WillOnce(Return(0)); |
| 518 .WillOnce(Return(0)); | |
| 519 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 484 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
| 520 .WillOnce(Return(kTestDeviceName)); | 485 .WillOnce(Return(kTestDeviceName)); |
| 521 test_stream->Close(); | 486 test_stream->Close(); |
| 522 } | 487 } |
| 523 | 488 |
| 524 TEST_F(AlsaPcmOutputStreamTest, WritePacket_WriteFails) { | 489 TEST_F(AlsaPcmOutputStreamTest, WritePacket_WriteFails) { |
| 525 // We need to open the stream before writing data to ALSA. | 490 // We need to open the stream before writing data to ALSA. |
| 526 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) | 491 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) |
| 527 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), | 492 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); |
| 528 Return(0))); | |
| 529 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) | 493 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) |
| 530 .WillOnce(Return(0)); | 494 .WillOnce(Return(0)); |
| 531 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) | 495 EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)).WillOnce( |
| 532 .WillOnce(DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), | 496 DoAll(SetArgumentPointee<1>(kTestFramesPerPacket), |
| 533 SetArgumentPointee<2>(kTestFramesPerPacket / 2), | 497 SetArgumentPointee<2>(kTestFramesPerPacket / 2), Return(0))); |
| 534 Return(0))); | |
| 535 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 498 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 536 ASSERT_TRUE(test_stream->Open()); | 499 ASSERT_TRUE(test_stream->Open()); |
| 537 InitBuffer(test_stream); | 500 InitBuffer(test_stream); |
| 538 test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying); | 501 test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying); |
| 539 | 502 |
| 540 // Fail due to a recoverable error and see that PcmRecover code path | 503 // Fail due to a recoverable error and see that PcmRecover code path |
| 541 // continues normally. | 504 // continues normally. |
| 542 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) | 505 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) |
| 543 .WillOnce(Return(kTestFramesPerPacket)); | 506 .WillOnce(Return(kTestFramesPerPacket)); |
| 544 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) | 507 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) |
| 545 .WillOnce(Return(-EINTR)); | 508 .WillOnce(Return(-EINTR)); |
| 546 EXPECT_CALL(mock_alsa_wrapper_, PcmRecover(kFakeHandle, _, _)) | 509 EXPECT_CALL(mock_alsa_wrapper_, PcmRecover(kFakeHandle, _, _)) |
| 547 .WillOnce(Return(0)); | 510 .WillOnce(Return(0)); |
| 548 | 511 |
| 549 test_stream->WritePacket(); | 512 test_stream->WritePacket(); |
| 550 | 513 |
| 551 ASSERT_EQ(test_stream->buffer_->forward_bytes(), packet_->GetDataSize()); | 514 ASSERT_EQ(test_stream->buffer_->forward_bytes(), packet_->get_data_size()); |
| 552 | 515 |
| 553 // Fail the next write, and see that stop_stream_ is set. | 516 // Fail the next write, and see that stop_stream_ is set. |
| 554 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) | 517 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) |
| 555 .WillOnce(Return(kTestFramesPerPacket)); | 518 .WillOnce(Return(kTestFramesPerPacket)); |
| 556 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) | 519 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) |
| 557 .WillOnce(Return(kTestFailedErrno)); | 520 .WillOnce(Return(kTestFailedErrno)); |
| 558 EXPECT_CALL(mock_alsa_wrapper_, PcmRecover(kFakeHandle, _, _)) | 521 EXPECT_CALL(mock_alsa_wrapper_, PcmRecover(kFakeHandle, _, _)) |
| 559 .WillOnce(Return(kTestFailedErrno)); | 522 .WillOnce(Return(kTestFailedErrno)); |
| 560 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) | 523 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) |
| 561 .WillOnce(Return(kDummyMessage)); | 524 .WillOnce(Return(kDummyMessage)); |
| 562 test_stream->WritePacket(); | 525 test_stream->WritePacket(); |
| 563 EXPECT_EQ(test_stream->buffer_->forward_bytes(), packet_->GetDataSize()); | 526 EXPECT_EQ(test_stream->buffer_->forward_bytes(), packet_->get_data_size()); |
| 564 EXPECT_TRUE(test_stream->stop_stream_); | 527 EXPECT_TRUE(test_stream->stop_stream_); |
| 565 | 528 |
| 566 // Now close it and test that everything was released. | 529 // Now close it and test that everything was released. |
| 567 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) | 530 EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)).WillOnce(Return(0)); |
| 568 .WillOnce(Return(0)); | |
| 569 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) | 531 EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) |
| 570 .WillOnce(Return(kTestDeviceName)); | 532 .WillOnce(Return(kTestDeviceName)); |
| 571 test_stream->Close(); | 533 test_stream->Close(); |
| 572 } | 534 } |
| 573 | 535 |
| 574 TEST_F(AlsaPcmOutputStreamTest, WritePacket_StopStream) { | 536 TEST_F(AlsaPcmOutputStreamTest, WritePacket_StopStream) { |
| 575 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 537 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 576 InitBuffer(test_stream); | 538 InitBuffer(test_stream); |
| 577 test_stream->TransitionTo(AlsaPcmOutputStream::kIsOpened); | 539 test_stream->TransitionTo(AlsaPcmOutputStream::kIsOpened); |
| 578 test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying); | 540 test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 603 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 642 InitBuffer(test_stream); | 604 InitBuffer(test_stream); |
| 643 test_stream->buffer_->Clear(); | 605 test_stream->buffer_->Clear(); |
| 644 | 606 |
| 645 // If ALSA has underrun then we should assume a delay of zero. | 607 // If ALSA has underrun then we should assume a delay of zero. |
| 646 MockAudioSourceCallback mock_callback; | 608 MockAudioSourceCallback mock_callback; |
| 647 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 609 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
| 648 .WillOnce(Return(SND_PCM_STATE_XRUN)); | 610 .WillOnce(Return(SND_PCM_STATE_XRUN)); |
| 649 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 611 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
| 650 .WillRepeatedly(Return(0)); // Buffer is full. | 612 .WillRepeatedly(Return(0)); // Buffer is full. |
| 651 EXPECT_CALL(mock_callback, | 613 EXPECT_CALL( |
| 652 OnMoreData(_, AllOf( | 614 mock_callback, |
| 653 Field(&AudioBuffersState::pending_bytes, 0), | 615 OnMoreData(_, AllOf(Field(&AudioBuffersState::pending_bytes, 0), |
| 654 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) | 616 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) |
| 655 .WillOnce(DoAll(ClearBuffer(), Return(kTestFramesPerPacket / 2))); | 617 .WillOnce(DoAll(ClearBuffer(), Return(kTestFramesPerPacket / 2))); |
| 656 | 618 |
| 657 bool source_exhausted; | 619 bool source_exhausted; |
| 658 test_stream->set_source_callback(&mock_callback); | 620 test_stream->set_source_callback(&mock_callback); |
| 659 test_stream->packet_size_ = kTestPacketSize; | 621 test_stream->packet_size_ = kTestPacketSize; |
| 660 test_stream->BufferPacket(&source_exhausted); | 622 test_stream->BufferPacket(&source_exhausted); |
| 661 | 623 |
| 662 EXPECT_EQ(kTestPacketSize / 2, test_stream->buffer_->forward_bytes()); | 624 EXPECT_EQ(kTestPacketSize / 2, test_stream->buffer_->forward_bytes()); |
| 663 EXPECT_FALSE(source_exhausted); | 625 EXPECT_FALSE(source_exhausted); |
| 664 test_stream->Close(); | 626 test_stream->Close(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 678 | 640 |
| 679 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_DeviceSelect) { | 641 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_DeviceSelect) { |
| 680 // Try channels from 1 -> 9. and see that we get the more specific surroundXX | 642 // Try channels from 1 -> 9. and see that we get the more specific surroundXX |
| 681 // device opened for channels 4-8. For all other channels, the device should | 643 // device opened for channels 4-8. For all other channels, the device should |
| 682 // default to |AlsaPcmOutputStream::kDefaultDevice|. We should also not | 644 // default to |AlsaPcmOutputStream::kDefaultDevice|. We should also not |
| 683 // downmix any channel in this case because downmixing is only defined for | 645 // downmix any channel in this case because downmixing is only defined for |
| 684 // channels 4-8, which we are guaranteeing to work. | 646 // channels 4-8, which we are guaranteeing to work. |
| 685 // | 647 // |
| 686 // Note that the loop starts at "1", so the first parameter is ignored in | 648 // Note that the loop starts at "1", so the first parameter is ignored in |
| 687 // these arrays. | 649 // these arrays. |
| 688 const char* kExpectedDeviceName[] = { NULL, | 650 const char* kExpectedDeviceName[] = { |
| 689 AlsaPcmOutputStream::kDefaultDevice, | 651 NULL, AlsaPcmOutputStream::kDefaultDevice, |
| 690 AlsaPcmOutputStream::kDefaultDevice, | 652 AlsaPcmOutputStream::kDefaultDevice, AlsaPcmOutputStream::kDefaultDevice, |
| 691 AlsaPcmOutputStream::kDefaultDevice, | 653 kSurround40, kSurround50, kSurround51, kSurround70, kSurround71, |
| 692 kSurround40, kSurround50, kSurround51, | 654 AlsaPcmOutputStream::kDefaultDevice |
| 693 kSurround70, kSurround71, | 655 }; |
| 694 AlsaPcmOutputStream::kDefaultDevice }; | 656 bool kExpectedDownmix[] = {false, false, false, false, false, true, false, |
| 695 bool kExpectedDownmix[] = { false, false, false, false, false, true, | 657 false, false, false}; |
| 696 false, false, false, false }; | 658 ChannelLayout kExpectedLayouts[] = { |
| 697 ChannelLayout kExpectedLayouts[] = { CHANNEL_LAYOUT_NONE, | 659 CHANNEL_LAYOUT_NONE, CHANNEL_LAYOUT_MONO, CHANNEL_LAYOUT_STEREO, |
| 698 CHANNEL_LAYOUT_MONO, | 660 CHANNEL_LAYOUT_SURROUND, CHANNEL_LAYOUT_4_0, CHANNEL_LAYOUT_5_0, |
| 699 CHANNEL_LAYOUT_STEREO, | 661 CHANNEL_LAYOUT_5_1, CHANNEL_LAYOUT_7_0, CHANNEL_LAYOUT_7_1 |
| 700 CHANNEL_LAYOUT_SURROUND, | 662 }; |
| 701 CHANNEL_LAYOUT_4_0, | |
| 702 CHANNEL_LAYOUT_5_0, | |
| 703 CHANNEL_LAYOUT_5_1, | |
| 704 CHANNEL_LAYOUT_7_0, | |
| 705 CHANNEL_LAYOUT_7_1 }; | |
| 706 | |
| 707 | 663 |
| 708 for (int i = 1; i < 9; ++i) { | 664 for (int i = 1; i < 9; ++i) { |
| 709 if (i == 3 || i == 4 || i == 5) // invalid number of channels | 665 if (i == 3 || i == 4 || i == 5) // invalid number of channels |
| 710 continue; | 666 continue; |
| 711 SCOPED_TRACE(base::StringPrintf("Attempting %d Channel", i)); | 667 SCOPED_TRACE(base::StringPrintf("Attempting %d Channel", i)); |
| 712 | 668 |
| 713 // Hints will only be grabbed for channel numbers that have non-default | 669 // Hints will only be grabbed for channel numbers that have non-default |
| 714 // devices associated with them. | 670 // devices associated with them. |
| 715 if (kExpectedDeviceName[i] != AlsaPcmOutputStream::kDefaultDevice) { | 671 if (kExpectedDeviceName[i] != AlsaPcmOutputStream::kDefaultDevice) { |
| 716 // The DeviceNameHint and DeviceNameFreeHint need to be paired to avoid a | 672 // The DeviceNameHint and DeviceNameFreeHint need to be paired to avoid a |
| 717 // memory leak. | 673 // memory leak. |
| 718 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameHint(_, _, _)) | 674 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameHint(_, _, _)) |
| 719 .WillOnce(DoAll(SetArgumentPointee<2>(&kFakeHints[0]), Return(0))); | 675 .WillOnce(DoAll(SetArgumentPointee<2>(&kFakeHints[0]), Return(0))); |
| 720 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameFreeHint(&kFakeHints[0])) | 676 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameFreeHint(&kFakeHints[0])) |
| 721 .Times(1); | 677 .Times(1); |
| 722 } | 678 } |
| 723 | 679 |
| 724 EXPECT_CALL(mock_alsa_wrapper_, | 680 EXPECT_CALL(mock_alsa_wrapper_, |
| 725 PcmOpen(_, StrEq(kExpectedDeviceName[i]), _, _)) | 681 PcmOpen(_, StrEq(kExpectedDeviceName[i]), _, _)) |
| 726 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); | 682 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); |
| 727 EXPECT_CALL(mock_alsa_wrapper_, | 683 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(kFakeHandle, _, _, i, _, _, _)) |
| 728 PcmSetParams(kFakeHandle, _, _, i, _, _, _)) | |
| 729 .WillOnce(Return(0)); | 684 .WillOnce(Return(0)); |
| 730 | 685 |
| 731 // The parameters are specified by ALSA documentation, and are in constants | 686 // The parameters are specified by ALSA documentation, and are in constants |
| 732 // in the implementation files. | 687 // in the implementation files. |
| 733 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("IOID"))) | 688 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("IOID"))) |
| 734 .WillRepeatedly(Invoke(OutputHint)); | 689 .WillRepeatedly(Invoke(OutputHint)); |
| 735 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("NAME"))) | 690 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("NAME"))) |
| 736 .WillRepeatedly(Invoke(EchoHint)); | 691 .WillRepeatedly(Invoke(EchoHint)); |
| 737 | 692 |
| 738 AlsaPcmOutputStream* test_stream = CreateStream(kExpectedLayouts[i]); | 693 AlsaPcmOutputStream* test_stream = CreateStream(kExpectedLayouts[i]); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 753 // operations should be as follows. Assume the multi-channel device name is | 708 // operations should be as follows. Assume the multi-channel device name is |
| 754 // surround50: | 709 // surround50: |
| 755 // | 710 // |
| 756 // 1) Try open "surround50" | 711 // 1) Try open "surround50" |
| 757 // 2) Try open "plug:surround50". | 712 // 2) Try open "plug:surround50". |
| 758 // 3) Try open "default". | 713 // 3) Try open "default". |
| 759 // 4) Try open "plug:default". | 714 // 4) Try open "plug:default". |
| 760 // 5) Give up trying to open. | 715 // 5) Give up trying to open. |
| 761 // | 716 // |
| 762 const string first_try = kSurround50; | 717 const string first_try = kSurround50; |
| 763 const string second_try = string(AlsaPcmOutputStream::kPlugPrefix) + | 718 const string second_try = |
| 764 kSurround50; | 719 string(AlsaPcmOutputStream::kPlugPrefix) + kSurround50; |
| 765 const string third_try = AlsaPcmOutputStream::kDefaultDevice; | 720 const string third_try = AlsaPcmOutputStream::kDefaultDevice; |
| 766 const string fourth_try = string(AlsaPcmOutputStream::kPlugPrefix) + | 721 const string fourth_try = string(AlsaPcmOutputStream::kPlugPrefix) + |
| 767 AlsaPcmOutputStream::kDefaultDevice; | 722 AlsaPcmOutputStream::kDefaultDevice; |
| 768 | 723 |
| 769 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameHint(_, _, _)) | 724 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameHint(_, _, _)) |
| 770 .WillOnce(DoAll(SetArgumentPointee<2>(&kFakeHints[0]), Return(0))); | 725 .WillOnce(DoAll(SetArgumentPointee<2>(&kFakeHints[0]), Return(0))); |
| 771 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameFreeHint(&kFakeHints[0])) | 726 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameFreeHint(&kFakeHints[0])).Times(1); |
| 772 .Times(1); | |
| 773 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("IOID"))) | 727 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("IOID"))) |
| 774 .WillRepeatedly(Invoke(OutputHint)); | 728 .WillRepeatedly(Invoke(OutputHint)); |
| 775 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("NAME"))) | 729 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameGetHint(_, StrEq("NAME"))) |
| 776 .WillRepeatedly(Invoke(EchoHint)); | 730 .WillRepeatedly(Invoke(EchoHint)); |
| 777 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) | 731 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) |
| 778 .WillRepeatedly(Return(kDummyMessage)); | 732 .WillRepeatedly(Return(kDummyMessage)); |
| 779 | 733 |
| 780 InSequence s; | 734 InSequence s; |
| 781 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(first_try.c_str()), _, _)) | 735 EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(first_try.c_str()), _, _)) |
| 782 .WillOnce(Return(kTestFailedErrno)); | 736 .WillOnce(Return(kTestFailedErrno)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 793 } | 747 } |
| 794 | 748 |
| 795 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_HintFail) { | 749 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_HintFail) { |
| 796 // Should get |kDefaultDevice|, and force a 2-channel downmix on a failure to | 750 // Should get |kDefaultDevice|, and force a 2-channel downmix on a failure to |
| 797 // enumerate devices. | 751 // enumerate devices. |
| 798 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameHint(_, _, _)) | 752 EXPECT_CALL(mock_alsa_wrapper_, DeviceNameHint(_, _, _)) |
| 799 .WillRepeatedly(Return(kTestFailedErrno)); | 753 .WillRepeatedly(Return(kTestFailedErrno)); |
| 800 EXPECT_CALL(mock_alsa_wrapper_, | 754 EXPECT_CALL(mock_alsa_wrapper_, |
| 801 PcmOpen(_, StrEq(AlsaPcmOutputStream::kDefaultDevice), _, _)) | 755 PcmOpen(_, StrEq(AlsaPcmOutputStream::kDefaultDevice), _, _)) |
| 802 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); | 756 .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); |
| 803 EXPECT_CALL(mock_alsa_wrapper_, | 757 EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(kFakeHandle, _, _, 2, _, _, _)) |
| 804 PcmSetParams(kFakeHandle, _, _, 2, _, _, _)) | |
| 805 .WillOnce(Return(0)); | 758 .WillOnce(Return(0)); |
| 806 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) | 759 EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) |
| 807 .WillOnce(Return(kDummyMessage)); | 760 .WillOnce(Return(kDummyMessage)); |
| 808 | 761 |
| 809 AlsaPcmOutputStream* test_stream = CreateStream(CHANNEL_LAYOUT_5_0); | 762 AlsaPcmOutputStream* test_stream = CreateStream(CHANNEL_LAYOUT_5_0); |
| 810 EXPECT_TRUE(test_stream->AutoSelectDevice(5)); | 763 EXPECT_TRUE(test_stream->AutoSelectDevice(5)); |
| 811 EXPECT_TRUE(test_stream->channel_mixer_); | 764 EXPECT_TRUE(test_stream->channel_mixer_); |
| 812 test_stream->Close(); | 765 test_stream->Close(); |
| 813 } | 766 } |
| 814 | 767 |
| 815 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_StopStream) { | 768 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_StopStream) { |
| 816 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 769 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 817 InitBuffer(test_stream); | 770 InitBuffer(test_stream); |
| 818 test_stream->stop_stream_ = true; | 771 test_stream->stop_stream_ = true; |
| 819 bool source_exhausted; | 772 bool source_exhausted; |
| 820 test_stream->BufferPacket(&source_exhausted); | 773 test_stream->BufferPacket(&source_exhausted); |
| 821 EXPECT_EQ(0, test_stream->buffer_->forward_bytes()); | 774 EXPECT_EQ(0, test_stream->buffer_->forward_bytes()); |
| 822 EXPECT_TRUE(source_exhausted); | 775 EXPECT_TRUE(source_exhausted); |
| 823 test_stream->Close(); | 776 test_stream->Close(); |
| 824 } | 777 } |
| 825 | 778 |
| 826 TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite) { | 779 TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite) { |
| 827 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 780 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 828 test_stream->TransitionTo(AlsaPcmOutputStream::kIsOpened); | 781 test_stream->TransitionTo(AlsaPcmOutputStream::kIsOpened); |
| 829 test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying); | 782 test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying); |
| 830 InitBuffer(test_stream); | 783 InitBuffer(test_stream); |
| 831 DVLOG(1) << test_stream->state(); | 784 DVLOG(1) << test_stream->state(); |
| 832 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 785 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)).WillOnce(Return(10)); |
| 833 .WillOnce(Return(10)); | |
| 834 test_stream->ScheduleNextWrite(false); | 786 test_stream->ScheduleNextWrite(false); |
| 835 DVLOG(1) << test_stream->state(); | 787 DVLOG(1) << test_stream->state(); |
| 836 // TODO(sergeyu): Figure out how to check that the task has been added to the | 788 // TODO(sergeyu): Figure out how to check that the task has been added to the |
| 837 // message loop. | 789 // message loop. |
| 838 | 790 |
| 839 // Cleanup the message queue. Currently ~MessageQueue() doesn't free pending | 791 // Cleanup the message queue. Currently ~MessageQueue() doesn't free pending |
| 840 // tasks unless running on valgrind. The code below is needed to keep | 792 // tasks unless running on valgrind. The code below is needed to keep |
| 841 // heapcheck happy. | 793 // heapcheck happy. |
| 842 | 794 |
| 843 test_stream->stop_stream_ = true; | 795 test_stream->stop_stream_ = true; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 859 | 811 |
| 860 // TODO(ajwong): Find a way to test whether or not another task has been | 812 // TODO(ajwong): Find a way to test whether or not another task has been |
| 861 // posted so we can verify that the Alsa code will indeed break the task | 813 // posted so we can verify that the Alsa code will indeed break the task |
| 862 // posting loop. | 814 // posting loop. |
| 863 | 815 |
| 864 test_stream->TransitionTo(AlsaPcmOutputStream::kIsClosed); | 816 test_stream->TransitionTo(AlsaPcmOutputStream::kIsClosed); |
| 865 test_stream->Close(); | 817 test_stream->Close(); |
| 866 } | 818 } |
| 867 | 819 |
| 868 } // namespace media | 820 } // namespace media |
| OLD | NEW |