virtual_audio_output_stream_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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/bind_helpers.h"
7#include "base/message_loop.h"
8#include "base/message_loop_proxy.h"
9#include "base/synchronization/waitable_event.h"
10#include "base/threading/thread.h"
11#include "media/audio/audio_manager.h"
12#include "media/audio/simple_sources.h"
13#include "media/audio/virtual_audio_input_stream.h"
14#include "media/audio/virtual_audio_output_stream.h"
15#include "testing/gmock/include/gmock/gmock.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18using ::testing::_;
19
20namespace media {
21
22namespace {
23const AudioParameters kParams(
24    AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_MONO, 8000, 8, 128);
25}
26
27class MockVirtualAudioInputStream : public VirtualAudioInputStream {
28 public:
29  explicit MockVirtualAudioInputStream(base::MessageLoopProxy* message_loop)
30      : VirtualAudioInputStream(
31            kParams,
32            message_loop,
33            base::Bind(&base::DeletePointer<VirtualAudioInputStream>)) {}
34  ~MockVirtualAudioInputStream() {}
35
36  MOCK_METHOD2(AddOutputStream, void(VirtualAudioOutputStream* stream,
37                                     const AudioParameters& output_params));
38  MOCK_METHOD2(RemoveOutputStream, void(VirtualAudioOutputStream* stream,
39                                        const AudioParameters& output_params));
40
41 private:
42  DISALLOW_COPY_AND_ASSIGN(MockVirtualAudioInputStream);
43};
44
45class MockAudioDeviceListener : public AudioManager::AudioDeviceListener {
46 public:
47  MOCK_METHOD0(OnDeviceChange, void());
48};
49
50class VirtualAudioOutputStreamTest : public testing::Test {
51 public:
52  VirtualAudioOutputStreamTest()
53      : audio_thread_(new base::Thread("AudioThread")) {
54    audio_thread_->Start();
55    audio_message_loop_ = audio_thread_->message_loop_proxy();
56  }
57
58  const scoped_refptr<base::MessageLoopProxy>& audio_message_loop() const {
59    return audio_message_loop_;
60  }
61
62  void SyncWithAudioThread() {
63    base::WaitableEvent done(false, false);
64    audio_message_loop()->PostTask(
65        FROM_HERE, base::Bind(&base::WaitableEvent::Signal,
66                              base::Unretained(&done)));
67    done.Wait();
68  }
69
70 private:
71  scoped_ptr<base::Thread> audio_thread_;
72  scoped_refptr<base::MessageLoopProxy> audio_message_loop_;
73
74  DISALLOW_COPY_AND_ASSIGN(VirtualAudioOutputStreamTest);
75};
76
77TEST_F(VirtualAudioOutputStreamTest, StartStopStartStop) {
78  static const int kCycles = 3;
79
80  MockVirtualAudioInputStream* const input_stream =
81      new MockVirtualAudioInputStream(audio_message_loop());
82  audio_message_loop()->PostTask(
83      FROM_HERE, base::Bind(
84          base::IgnoreResult(&MockVirtualAudioInputStream::Open),
85          base::Unretained(input_stream)));
86
87  VirtualAudioOutputStream* const output_stream =
88      new VirtualAudioOutputStream(
89          kParams, audio_message_loop(), input_stream,
90          base::Bind(&base::DeletePointer<VirtualAudioOutputStream>));
91
92  EXPECT_CALL(*input_stream, AddOutputStream(output_stream, _))
93      .Times(kCycles);
94  EXPECT_CALL(*input_stream, RemoveOutputStream(output_stream, _))
95      .Times(kCycles);
96
97  audio_message_loop()->PostTask(
98      FROM_HERE, base::Bind(base::IgnoreResult(&VirtualAudioOutputStream::Open),
99                            base::Unretained(output_stream)));
100  SineWaveAudioSource source(CHANNEL_LAYOUT_STEREO, 200.0, 128);
101  for (int i = 0; i < kCycles; ++i) {
102    audio_message_loop()->PostTask(
103        FROM_HERE, base::Bind(&VirtualAudioOutputStream::Start,
104                              base::Unretained(output_stream),
105                              &source));
106    audio_message_loop()->PostTask(
107        FROM_HERE, base::Bind(&VirtualAudioOutputStream::Stop,
108                              base::Unretained(output_stream)));
109  }
110  audio_message_loop()->PostTask(
111      FROM_HERE, base::Bind(&VirtualAudioOutputStream::Close,
112                            base::Unretained(output_stream)));
113
114  audio_message_loop()->PostTask(
115      FROM_HERE, base::Bind(&MockVirtualAudioInputStream::Close,
116                            base::Unretained(input_stream)));
117
118  SyncWithAudioThread();
119}
120
121}  // namespace media
122