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