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