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