Make Chromoting browser tests pass again
[chromium-blink-merge.git] / media / audio / audio_output_device_unittest.cc
blob363ee3894070eb0c025520c3fa6b05091c273bb3
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.
5 #include <vector>
7 #include "base/at_exit.h"
8 #include "base/memory/shared_memory.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/process/process_handle.h"
11 #include "base/sync_socket.h"
12 #include "base/test/test_timeouts.h"
13 #include "media/audio/audio_output_device.h"
14 #include "media/audio/sample_rates.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gmock_mutant.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 using base::CancelableSyncSocket;
20 using base::SharedMemory;
21 using base::SyncSocket;
22 using testing::_;
23 using testing::DoAll;
24 using testing::Invoke;
25 using testing::Return;
26 using testing::WithArgs;
27 using testing::StrictMock;
28 using testing::Values;
30 namespace media {
32 namespace {
34 class MockRenderCallback : public AudioRendererSink::RenderCallback {
35 public:
36 MockRenderCallback() {}
37 virtual ~MockRenderCallback() {}
39 MOCK_METHOD2(Render, int(AudioBus* dest, int audio_delay_milliseconds));
40 MOCK_METHOD0(OnRenderError, void());
43 class MockAudioOutputIPC : public AudioOutputIPC {
44 public:
45 MockAudioOutputIPC() {}
46 virtual ~MockAudioOutputIPC() {}
48 MOCK_METHOD3(CreateStream, void(AudioOutputIPCDelegate* delegate,
49 const AudioParameters& params,
50 int session_id));
51 MOCK_METHOD0(PlayStream, void());
52 MOCK_METHOD0(PauseStream, void());
53 MOCK_METHOD0(CloseStream, void());
54 MOCK_METHOD1(SetVolume, void(double volume));
57 ACTION_P2(SendPendingBytes, socket, pending_bytes) {
58 socket->Send(&pending_bytes, sizeof(pending_bytes));
61 // Used to terminate a loop from a different thread than the loop belongs to.
62 // |loop| should be a MessageLoopProxy.
63 ACTION_P(QuitLoop, loop) {
64 loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
67 } // namespace.
69 class AudioOutputDeviceTest
70 : public testing::Test,
71 public testing::WithParamInterface<bool> {
72 public:
73 AudioOutputDeviceTest();
74 ~AudioOutputDeviceTest();
76 void StartAudioDevice();
77 void CreateStream();
78 void ExpectRenderCallback();
79 void WaitUntilRenderCallback();
80 void StopAudioDevice();
82 protected:
83 // Used to clean up TLS pointers that the test(s) will initialize.
84 // Must remain the first member of this class.
85 base::ShadowingAtExitManager at_exit_manager_;
86 base::MessageLoopForIO io_loop_;
87 AudioParameters default_audio_parameters_;
88 StrictMock<MockRenderCallback> callback_;
89 MockAudioOutputIPC* audio_output_ipc_; // owned by audio_device_
90 scoped_refptr<AudioOutputDevice> audio_device_;
92 private:
93 int CalculateMemorySize();
95 SharedMemory shared_memory_;
96 CancelableSyncSocket browser_socket_;
97 CancelableSyncSocket renderer_socket_;
99 DISALLOW_COPY_AND_ASSIGN(AudioOutputDeviceTest);
102 int AudioOutputDeviceTest::CalculateMemorySize() {
103 // Calculate output memory size.
104 return AudioBus::CalculateMemorySize(default_audio_parameters_);
107 AudioOutputDeviceTest::AudioOutputDeviceTest() {
108 default_audio_parameters_.Reset(
109 AudioParameters::AUDIO_PCM_LINEAR,
110 CHANNEL_LAYOUT_STEREO, 2, 48000, 16, 1024);
112 audio_output_ipc_ = new MockAudioOutputIPC();
113 audio_device_ = new AudioOutputDevice(
114 scoped_ptr<AudioOutputIPC>(audio_output_ipc_),
115 io_loop_.message_loop_proxy());
117 audio_device_->Initialize(default_audio_parameters_,
118 &callback_);
120 io_loop_.RunUntilIdle();
123 AudioOutputDeviceTest::~AudioOutputDeviceTest() {
124 audio_device_ = NULL;
127 void AudioOutputDeviceTest::StartAudioDevice() {
128 audio_device_->Start();
130 EXPECT_CALL(*audio_output_ipc_, CreateStream(audio_device_.get(), _, 0));
132 io_loop_.RunUntilIdle();
135 void AudioOutputDeviceTest::CreateStream() {
136 const int kMemorySize = CalculateMemorySize();
138 ASSERT_TRUE(shared_memory_.CreateAndMapAnonymous(kMemorySize));
139 memset(shared_memory_.memory(), 0xff, kMemorySize);
141 ASSERT_TRUE(CancelableSyncSocket::CreatePair(&browser_socket_,
142 &renderer_socket_));
144 // Create duplicates of the handles we pass to AudioOutputDevice since
145 // ownership will be transferred and AudioOutputDevice is responsible for
146 // freeing.
147 SyncSocket::TransitDescriptor audio_device_socket_descriptor;
148 ASSERT_TRUE(renderer_socket_.PrepareTransitDescriptor(
149 base::GetCurrentProcessHandle(), &audio_device_socket_descriptor));
150 base::SharedMemoryHandle duplicated_memory_handle;
151 ASSERT_TRUE(shared_memory_.ShareToProcess(base::GetCurrentProcessHandle(),
152 &duplicated_memory_handle));
154 audio_device_->OnStreamCreated(
155 duplicated_memory_handle,
156 SyncSocket::UnwrapHandle(audio_device_socket_descriptor), kMemorySize);
157 io_loop_.RunUntilIdle();
160 void AudioOutputDeviceTest::ExpectRenderCallback() {
161 // We should get a 'play' notification when we call OnStreamCreated().
162 // Respond by asking for some audio data. This should ask our callback
163 // to provide some audio data that AudioOutputDevice then writes into the
164 // shared memory section.
165 const int kMemorySize = CalculateMemorySize();
167 EXPECT_CALL(*audio_output_ipc_, PlayStream())
168 .WillOnce(SendPendingBytes(&browser_socket_, kMemorySize));
170 // We expect calls to our audio renderer callback, which returns the number
171 // of frames written to the memory section.
172 // Here's the second place where it gets hacky: There's no way for us to
173 // know (without using a sleep loop!) when the AudioOutputDevice has finished
174 // writing the interleaved audio data into the shared memory section.
175 // So, for the sake of this test, we consider the call to Render a sign
176 // of success and quit the loop.
177 const int kNumberOfFramesToProcess = 0;
178 EXPECT_CALL(callback_, Render(_, _))
179 .WillOnce(DoAll(
180 QuitLoop(io_loop_.message_loop_proxy()),
181 Return(kNumberOfFramesToProcess)));
184 void AudioOutputDeviceTest::WaitUntilRenderCallback() {
185 // Don't hang the test if we never get the Render() callback.
186 io_loop_.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(),
187 TestTimeouts::action_timeout());
188 io_loop_.Run();
191 void AudioOutputDeviceTest::StopAudioDevice() {
192 audio_device_->Stop();
194 EXPECT_CALL(*audio_output_ipc_, CloseStream());
196 io_loop_.RunUntilIdle();
199 TEST_P(AudioOutputDeviceTest, Initialize) {
200 // Tests that the object can be constructed, initialized and destructed
201 // without having ever been started/stopped.
204 // Calls Start() followed by an immediate Stop() and check for the basic message
205 // filter messages being sent in that case.
206 TEST_P(AudioOutputDeviceTest, StartStop) {
207 StartAudioDevice();
208 StopAudioDevice();
211 // AudioOutputDevice supports multiple start/stop sequences.
212 TEST_P(AudioOutputDeviceTest, StartStopStartStop) {
213 StartAudioDevice();
214 StopAudioDevice();
215 StartAudioDevice();
216 StopAudioDevice();
219 // Simulate receiving OnStreamCreated() prior to processing ShutDownOnIOThread()
220 // on the IO loop.
221 TEST_P(AudioOutputDeviceTest, StopBeforeRender) {
222 StartAudioDevice();
224 // Call Stop() but don't run the IO loop yet.
225 audio_device_->Stop();
227 // Expect us to shutdown IPC but not to render anything despite the stream
228 // getting created.
229 EXPECT_CALL(*audio_output_ipc_, CloseStream());
230 CreateStream();
233 // Full test with output only.
234 TEST_P(AudioOutputDeviceTest, CreateStream) {
235 StartAudioDevice();
236 ExpectRenderCallback();
237 CreateStream();
238 WaitUntilRenderCallback();
239 StopAudioDevice();
242 INSTANTIATE_TEST_CASE_P(Render, AudioOutputDeviceTest, Values(false));
244 } // namespace media.