Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / media / audio / fake_audio_consumer_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/bind.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/time/time.h"
8 #include "media/audio/audio_parameters.h"
9 #include "media/audio/fake_audio_consumer.h"
10 #include "media/audio/simple_sources.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace media {
14
15 static const int kTestCallbacks = 5;
16
17 class FakeAudioConsumerTest : public testing::Test {
18  public:
19   FakeAudioConsumerTest()
20       : params_(
21             AudioParameters::AUDIO_FAKE, CHANNEL_LAYOUT_STEREO, 44100, 8, 128),
22         fake_consumer_(message_loop_.message_loop_proxy(), params_),
23         source_(params_.channels(), 200.0, params_.sample_rate()) {
24     time_between_callbacks_ = base::TimeDelta::FromMicroseconds(
25         params_.frames_per_buffer() * base::Time::kMicrosecondsPerSecond /
26         static_cast<float>(params_.sample_rate()));
27   }
28
29   ~FakeAudioConsumerTest() override {}
30
31   void ConsumeData(AudioBus* audio_bus) {
32     source_.OnMoreData(audio_bus, 0);
33   }
34
35   void RunOnAudioThread() {
36     ASSERT_TRUE(message_loop_.message_loop_proxy()->BelongsToCurrentThread());
37     fake_consumer_.Start(base::Bind(
38         &FakeAudioConsumerTest::ConsumeData, base::Unretained(this)));
39   }
40
41   void RunOnceOnAudioThread() {
42     ASSERT_TRUE(message_loop_.message_loop_proxy()->BelongsToCurrentThread());
43     RunOnAudioThread();
44     // Start() should immediately post a task to run the source callback, so we
45     // should end up with only a single callback being run.
46     message_loop_.PostTask(FROM_HERE, base::Bind(
47         &FakeAudioConsumerTest::EndTest, base::Unretained(this), 1));
48   }
49
50   void StopStartOnAudioThread() {
51     ASSERT_TRUE(message_loop_.message_loop_proxy()->BelongsToCurrentThread());
52     fake_consumer_.Stop();
53     RunOnAudioThread();
54   }
55
56   void TimeCallbacksOnAudioThread(int callbacks) {
57     ASSERT_TRUE(message_loop_.message_loop_proxy()->BelongsToCurrentThread());
58
59     if (source_.callbacks() == 0) {
60       RunOnAudioThread();
61       start_time_ = base::TimeTicks::Now();
62     }
63
64     // Keep going until we've seen the requested number of callbacks.
65     if (source_.callbacks() < callbacks) {
66       message_loop_.PostDelayedTask(FROM_HERE, base::Bind(
67           &FakeAudioConsumerTest::TimeCallbacksOnAudioThread,
68           base::Unretained(this), callbacks), time_between_callbacks_ / 2);
69     } else {
70       end_time_ = base::TimeTicks::Now();
71       EndTest(callbacks);
72     }
73   }
74
75   void EndTest(int callbacks) {
76     ASSERT_TRUE(message_loop_.message_loop_proxy()->BelongsToCurrentThread());
77     fake_consumer_.Stop();
78     EXPECT_LE(callbacks, source_.callbacks());
79     message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
80   }
81
82  protected:
83   base::MessageLoop message_loop_;
84   AudioParameters params_;
85   FakeAudioConsumer fake_consumer_;
86   SineWaveAudioSource source_;
87   base::TimeTicks start_time_;
88   base::TimeTicks end_time_;
89   base::TimeDelta time_between_callbacks_;
90
91  private:
92   DISALLOW_COPY_AND_ASSIGN(FakeAudioConsumerTest);
93 };
94
95 // Ensure the fake audio stream runs on the audio thread and handles fires
96 // callbacks to the AudioSourceCallback.
97 TEST_F(FakeAudioConsumerTest, FakeStreamBasicCallback) {
98   message_loop_.PostTask(FROM_HERE, base::Bind(
99       &FakeAudioConsumerTest::RunOnceOnAudioThread,
100       base::Unretained(this)));
101   message_loop_.Run();
102 }
103
104 // Ensure the time between callbacks is sane.
105 TEST_F(FakeAudioConsumerTest, TimeBetweenCallbacks) {
106   message_loop_.PostTask(FROM_HERE, base::Bind(
107       &FakeAudioConsumerTest::TimeCallbacksOnAudioThread,
108       base::Unretained(this), kTestCallbacks));
109   message_loop_.Run();
110
111   // There are only (kTestCallbacks - 1) intervals between kTestCallbacks.
112   base::TimeDelta actual_time_between_callbacks =
113       (end_time_ - start_time_) / (source_.callbacks() - 1);
114
115   // Ensure callback time is no faster than the expected time between callbacks.
116   EXPECT_TRUE(actual_time_between_callbacks >= time_between_callbacks_);
117
118   // Softly check if the callback time is no slower than twice the expected time
119   // between callbacks.  Since this test runs on the bots we can't be too strict
120   // with the bounds.
121   if (actual_time_between_callbacks > 2 * time_between_callbacks_)
122     LOG(ERROR) << "Time between fake audio callbacks is too large!";
123 }
124
125 // Ensure Start()/Stop() on the stream doesn't generate too many callbacks.  See
126 // http://crbug.com/159049
127 TEST_F(FakeAudioConsumerTest, StartStopClearsCallbacks) {
128   message_loop_.PostTask(FROM_HERE, base::Bind(
129       &FakeAudioConsumerTest::TimeCallbacksOnAudioThread,
130       base::Unretained(this), kTestCallbacks));
131
132   // Issue a Stop() / Start() in between expected callbacks to maximize the
133   // chance of catching the FakeAudioOutputStream doing the wrong thing.
134   message_loop_.PostDelayedTask(FROM_HERE, base::Bind(
135       &FakeAudioConsumerTest::StopStartOnAudioThread,
136       base::Unretained(this)), time_between_callbacks_ / 2);
137
138   // EndTest() will ensure the proper number of callbacks have occurred.
139   message_loop_.Run();
140 }
141
142 }  // namespace media