Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / media / audio / audio_output_controller_unittest.cc
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
3 // found in the LICENSE file.
4
5 #include "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/environment.h"
8 #include "base/logging.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "media/audio/audio_manager_base.h"
14 #include "media/audio/audio_output_controller.h"
15 #include "media/audio/audio_parameters.h"
16 #include "media/base/audio_bus.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 using ::testing::_;
21 using ::testing::AtLeast;
22 using ::testing::DoAll;
23 using ::testing::Invoke;
24 using ::testing::NotNull;
25 using ::testing::Return;
26
27 namespace media {
28
29 static const int kSampleRate = AudioParameters::kAudioCDSampleRate;
30 static const int kBitsPerSample = 16;
31 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
32 static const int kSamplesPerPacket = kSampleRate / 100;
33 static const double kTestVolume = 0.25;
34
35 class MockAudioOutputControllerEventHandler
36     : public AudioOutputController::EventHandler {
37  public:
38   MockAudioOutputControllerEventHandler() {}
39
40   MOCK_METHOD0(OnCreated, void());
41   MOCK_METHOD0(OnPlaying, void());
42   MOCK_METHOD0(OnPaused, void());
43   MOCK_METHOD0(OnError, void());
44   MOCK_METHOD2(OnDeviceChange, void(int new_buffer_size, int new_sample_rate));
45
46  private:
47   DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerEventHandler);
48 };
49
50 class MockAudioOutputControllerSyncReader
51     : public AudioOutputController::SyncReader {
52  public:
53   MockAudioOutputControllerSyncReader() {}
54
55   MOCK_METHOD1(UpdatePendingBytes, void(uint32 bytes));
56   MOCK_METHOD1(Read, void(AudioBus* dest));
57   MOCK_METHOD0(Close, void());
58
59  private:
60   DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerSyncReader);
61 };
62
63 class MockAudioOutputStream : public AudioOutputStream {
64  public:
65   MOCK_METHOD0(Open, bool());
66   MOCK_METHOD1(Start, void(AudioSourceCallback* callback));
67   MOCK_METHOD0(Stop, void());
68   MOCK_METHOD1(SetVolume, void(double volume));
69   MOCK_METHOD1(GetVolume, void(double* volume));
70   MOCK_METHOD0(Close, void());
71
72   // Set/get the callback passed to Start().
73   AudioSourceCallback* callback() const { return callback_; }
74   void SetCallback(AudioSourceCallback* asc) { callback_ = asc; }
75
76  private:
77   AudioSourceCallback* callback_;
78 };
79
80 ACTION_P(SignalEvent, event) {
81   event->Signal();
82 }
83
84 static const float kBufferNonZeroData = 1.0f;
85 ACTION(PopulateBuffer) {
86   arg0->Zero();
87   // Note: To confirm the buffer will be populated in these tests, it's
88   // sufficient that only the first float in channel 0 is set to the value.
89   arg0->channel(0)[0] = kBufferNonZeroData;
90 }
91
92 class AudioOutputControllerTest : public testing::Test {
93  public:
94   AudioOutputControllerTest()
95       : audio_manager_(AudioManager::CreateForTesting()),
96         create_event_(false, false),
97         play_event_(false, false),
98         read_event_(false, false),
99         pause_event_(false, false) {
100   }
101
102   ~AudioOutputControllerTest() override {}
103
104  protected:
105   void Create(int samples_per_packet) {
106     EXPECT_FALSE(create_event_.IsSignaled());
107     EXPECT_FALSE(play_event_.IsSignaled());
108     EXPECT_FALSE(read_event_.IsSignaled());
109     EXPECT_FALSE(pause_event_.IsSignaled());
110
111     params_ = AudioParameters(
112         AudioParameters::AUDIO_FAKE, kChannelLayout,
113         kSampleRate, kBitsPerSample, samples_per_packet);
114
115     if (params_.IsValid()) {
116       EXPECT_CALL(mock_event_handler_, OnCreated())
117           .WillOnce(SignalEvent(&create_event_));
118     }
119
120     controller_ = AudioOutputController::Create(
121         audio_manager_.get(), &mock_event_handler_, params_, std::string(),
122         &mock_sync_reader_);
123     if (controller_.get())
124       controller_->SetVolume(kTestVolume);
125
126     EXPECT_EQ(params_.IsValid(), controller_.get() != NULL);
127   }
128
129   void Play() {
130     // Expect the event handler to receive one OnPlaying() call.
131     EXPECT_CALL(mock_event_handler_, OnPlaying())
132         .WillOnce(SignalEvent(&play_event_));
133
134     // During playback, the mock pretends to provide audio data rendered and
135     // sent from the render process.
136     EXPECT_CALL(mock_sync_reader_, UpdatePendingBytes(_))
137         .Times(AtLeast(1));
138     EXPECT_CALL(mock_sync_reader_, Read(_))
139         .WillRepeatedly(DoAll(PopulateBuffer(),
140                               SignalEvent(&read_event_)));
141     controller_->Play();
142   }
143
144   void Pause() {
145     // Expect the event handler to receive one OnPaused() call.
146     EXPECT_CALL(mock_event_handler_, OnPaused())
147         .WillOnce(SignalEvent(&pause_event_));
148
149     controller_->Pause();
150   }
151
152   void ChangeDevice() {
153     // Expect the event handler to receive one OnPaying() call and no OnPaused()
154     // call.
155     EXPECT_CALL(mock_event_handler_, OnPlaying())
156         .WillOnce(SignalEvent(&play_event_));
157     EXPECT_CALL(mock_event_handler_, OnPaused())
158         .Times(0);
159
160     // Simulate a device change event to AudioOutputController from the
161     // AudioManager.
162     audio_manager_->GetTaskRunner()->PostTask(
163         FROM_HERE,
164         base::Bind(&AudioOutputController::OnDeviceChange, controller_));
165   }
166
167   void Divert(bool was_playing, int num_times_to_be_started) {
168     if (was_playing) {
169       // Expect the handler to receive one OnPlaying() call as a result of the
170       // stream switching.
171       EXPECT_CALL(mock_event_handler_, OnPlaying())
172           .WillOnce(SignalEvent(&play_event_));
173     }
174
175     EXPECT_CALL(mock_stream_, Open())
176         .WillOnce(Return(true));
177     EXPECT_CALL(mock_stream_, SetVolume(kTestVolume));
178     if (num_times_to_be_started > 0) {
179       EXPECT_CALL(mock_stream_, Start(NotNull()))
180           .Times(num_times_to_be_started)
181           .WillRepeatedly(
182               Invoke(&mock_stream_, &MockAudioOutputStream::SetCallback));
183       EXPECT_CALL(mock_stream_, Stop())
184           .Times(num_times_to_be_started);
185     }
186
187     controller_->StartDiverting(&mock_stream_);
188   }
189
190   void ReadDivertedAudioData() {
191     scoped_ptr<AudioBus> dest = AudioBus::Create(params_);
192     ASSERT_TRUE(!!mock_stream_.callback());
193     const int frames_read =
194         mock_stream_.callback()->OnMoreData(dest.get(), 0);
195     EXPECT_LT(0, frames_read);
196     EXPECT_EQ(kBufferNonZeroData, dest->channel(0)[0]);
197   }
198
199   void Revert(bool was_playing) {
200     if (was_playing) {
201       // Expect the handler to receive one OnPlaying() call as a result of the
202       // stream switching back.
203       EXPECT_CALL(mock_event_handler_, OnPlaying())
204           .WillOnce(SignalEvent(&play_event_));
205     }
206
207     EXPECT_CALL(mock_stream_, Close());
208
209     controller_->StopDiverting();
210   }
211
212   void SwitchDevice(bool diverting) {
213     if (!diverting) {
214       // Expect the current stream to close and a new stream to start
215       // playing if not diverting. When diverting, nothing happens
216       // until diverting is stopped.
217       EXPECT_CALL(mock_event_handler_, OnPlaying())
218           .WillOnce(SignalEvent(&play_event_));
219     }
220
221     controller_->SwitchOutputDevice(AudioManagerBase::kDefaultDeviceName,
222                                     base::Bind(&base::DoNothing));
223   }
224
225   void Close() {
226     EXPECT_CALL(mock_sync_reader_, Close());
227
228     controller_->Close(base::MessageLoop::QuitClosure());
229     base::MessageLoop::current()->Run();
230   }
231
232   // These help make test sequences more readable.
233   void DivertNeverPlaying() { Divert(false, 0); }
234   void DivertWillEventuallyBeTwicePlayed() { Divert(false, 2); }
235   void DivertWhilePlaying() { Divert(true, 1); }
236   void RevertWasNotPlaying() { Revert(false); }
237   void RevertWhilePlaying() { Revert(true); }
238
239   // These synchronize the main thread with key events taking place on other
240   // threads.
241   void WaitForCreate() { create_event_.Wait(); }
242   void WaitForPlay() { play_event_.Wait(); }
243   void WaitForReads() {
244     // Note: Arbitrarily chosen, but more iterations causes tests to take
245     // significantly more time.
246     static const int kNumIterations = 3;
247     for (int i = 0; i < kNumIterations; ++i) {
248       read_event_.Wait();
249     }
250   }
251   void WaitForPause() { pause_event_.Wait(); }
252
253  private:
254   base::MessageLoopForIO message_loop_;
255   scoped_ptr<AudioManager> audio_manager_;
256   MockAudioOutputControllerEventHandler mock_event_handler_;
257   MockAudioOutputControllerSyncReader mock_sync_reader_;
258   MockAudioOutputStream mock_stream_;
259   base::WaitableEvent create_event_;
260   base::WaitableEvent play_event_;
261   base::WaitableEvent read_event_;
262   base::WaitableEvent pause_event_;
263   AudioParameters params_;
264   scoped_refptr<AudioOutputController> controller_;
265
266   DISALLOW_COPY_AND_ASSIGN(AudioOutputControllerTest);
267 };
268
269 TEST_F(AudioOutputControllerTest, CreateAndClose) {
270   Create(kSamplesPerPacket);
271   Close();
272 }
273
274 TEST_F(AudioOutputControllerTest, HardwareBufferTooLarge) {
275   Create(kSamplesPerPacket * 1000);
276 }
277
278 TEST_F(AudioOutputControllerTest, PlayAndClose) {
279   Create(kSamplesPerPacket);
280   WaitForCreate();
281   Play();
282   WaitForPlay();
283   WaitForReads();
284   Close();
285 }
286
287 TEST_F(AudioOutputControllerTest, PlayPauseClose) {
288   Create(kSamplesPerPacket);
289   WaitForCreate();
290   Play();
291   WaitForPlay();
292   WaitForReads();
293   Pause();
294   WaitForPause();
295   Close();
296 }
297
298 TEST_F(AudioOutputControllerTest, PlayPausePlayClose) {
299   Create(kSamplesPerPacket);
300   WaitForCreate();
301   Play();
302   WaitForPlay();
303   WaitForReads();
304   Pause();
305   WaitForPause();
306   Play();
307   WaitForPlay();
308   Close();
309 }
310
311 TEST_F(AudioOutputControllerTest, PlayDeviceChangeClose) {
312   Create(kSamplesPerPacket);
313   WaitForCreate();
314   Play();
315   WaitForPlay();
316   WaitForReads();
317   ChangeDevice();
318   WaitForPlay();
319   WaitForReads();
320   Close();
321 }
322
323 TEST_F(AudioOutputControllerTest, PlaySwitchDeviceClose) {
324   Create(kSamplesPerPacket);
325   WaitForCreate();
326   Play();
327   WaitForPlay();
328   WaitForReads();
329   SwitchDevice(false);
330   WaitForPlay();
331   WaitForReads();
332   Close();
333 }
334
335 TEST_F(AudioOutputControllerTest, PlayDivertRevertClose) {
336   Create(kSamplesPerPacket);
337   WaitForCreate();
338   Play();
339   WaitForPlay();
340   WaitForReads();
341   DivertWhilePlaying();
342   WaitForPlay();
343   ReadDivertedAudioData();
344   RevertWhilePlaying();
345   WaitForPlay();
346   WaitForReads();
347   Close();
348 }
349
350 TEST_F(AudioOutputControllerTest, PlayDivertSwitchDeviceRevertClose) {
351   Create(kSamplesPerPacket);
352   WaitForCreate();
353   Play();
354   WaitForPlay();
355   WaitForReads();
356   DivertWhilePlaying();
357   WaitForPlay();
358   SwitchDevice(true);
359   ReadDivertedAudioData();
360   RevertWhilePlaying();
361   WaitForPlay();
362   WaitForReads();
363   Close();
364 }
365
366 TEST_F(AudioOutputControllerTest, PlayDivertRevertDivertRevertClose) {
367   Create(kSamplesPerPacket);
368   WaitForCreate();
369   Play();
370   WaitForPlay();
371   WaitForReads();
372   DivertWhilePlaying();
373   WaitForPlay();
374   ReadDivertedAudioData();
375   RevertWhilePlaying();
376   WaitForPlay();
377   WaitForReads();
378   DivertWhilePlaying();
379   WaitForPlay();
380   ReadDivertedAudioData();
381   RevertWhilePlaying();
382   WaitForPlay();
383   WaitForReads();
384   Close();
385 }
386
387 TEST_F(AudioOutputControllerTest, DivertPlayPausePlayRevertClose) {
388   Create(kSamplesPerPacket);
389   WaitForCreate();
390   DivertWillEventuallyBeTwicePlayed();
391   Play();
392   WaitForPlay();
393   ReadDivertedAudioData();
394   Pause();
395   WaitForPause();
396   Play();
397   WaitForPlay();
398   ReadDivertedAudioData();
399   RevertWhilePlaying();
400   WaitForPlay();
401   WaitForReads();
402   Close();
403 }
404
405 TEST_F(AudioOutputControllerTest, DivertRevertClose) {
406   Create(kSamplesPerPacket);
407   WaitForCreate();
408   DivertNeverPlaying();
409   RevertWasNotPlaying();
410   Close();
411 }
412
413 }  // namespace media