This source file includes following definitions.
- DuplicateSocketHandle
 
- ACTION_P2
 
- ACTION_P
 
- CalculateMemorySize
 
- input_channels_
 
- StartAudioDevice
 
- CreateStream
 
- ExpectRenderCallback
 
- WaitUntilRenderCallback
 
- StopAudioDevice
 
- TEST_P
 
- TEST_P
 
- TEST_P
 
- TEST_P
 
- TEST_P
 
#include <vector>
#include "base/at_exit.h"
#include "base/memory/shared_memory.h"
#include "base/message_loop/message_loop.h"
#include "base/process/process_handle.h"
#include "base/sync_socket.h"
#include "base/test/test_timeouts.h"
#include "media/audio/audio_output_device.h"
#include "media/audio/sample_rates.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gmock_mutant.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::CancelableSyncSocket;
using base::SharedMemory;
using base::SyncSocket;
using testing::_;
using testing::DoAll;
using testing::Invoke;
using testing::Return;
using testing::WithArgs;
using testing::StrictMock;
using testing::Values;
namespace media {
namespace {
class MockRenderCallback : public AudioRendererSink::RenderCallback {
 public:
  MockRenderCallback() {}
  virtual ~MockRenderCallback() {}
  MOCK_METHOD2(Render, int(AudioBus* dest, int audio_delay_milliseconds));
  MOCK_METHOD3(RenderIO, void(AudioBus* source,
                              AudioBus* dest,
                              int audio_delay_milliseconds));
  MOCK_METHOD0(OnRenderError, void());
};
class MockAudioOutputIPC : public AudioOutputIPC {
 public:
  MockAudioOutputIPC() {}
  virtual ~MockAudioOutputIPC() {}
  MOCK_METHOD3(CreateStream, void(AudioOutputIPCDelegate* delegate,
                                  const AudioParameters& params,
                                  int session_id));
  MOCK_METHOD0(PlayStream, void());
  MOCK_METHOD0(PauseStream, void());
  MOCK_METHOD0(CloseStream, void());
  MOCK_METHOD1(SetVolume, void(double volume));
};
bool DuplicateSocketHandle(SyncSocket::Handle socket_handle,
                           SyncSocket::Handle* copy) {
#if defined(OS_WIN)
  HANDLE process = GetCurrentProcess();
  ::DuplicateHandle(process, socket_handle, process, copy,
                    0, FALSE, DUPLICATE_SAME_ACCESS);
  return *copy != NULL;
#else
  *copy = socket_handle;
  return *copy != -1;
#endif
}
ACTION_P2(SendPendingBytes, socket, pending_bytes) {
  socket->Send(&pending_bytes, sizeof(pending_bytes));
}
ACTION_P(QuitLoop, loop) {
  loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
}
}  
class AudioOutputDeviceTest
    : public testing::Test,
      public testing::WithParamInterface<bool> {
 public:
  AudioOutputDeviceTest();
  ~AudioOutputDeviceTest();
  void StartAudioDevice();
  void CreateStream();
  void ExpectRenderCallback();
  void WaitUntilRenderCallback();
  void StopAudioDevice();
 protected:
  
  
  base::ShadowingAtExitManager at_exit_manager_;
  base::MessageLoopForIO io_loop_;
  AudioParameters default_audio_parameters_;
  StrictMock<MockRenderCallback> callback_;
  MockAudioOutputIPC* audio_output_ipc_;  
  scoped_refptr<AudioOutputDevice> audio_device_;
 private:
  int CalculateMemorySize();
  const bool synchronized_io_;
  const int input_channels_;
  SharedMemory shared_memory_;
  CancelableSyncSocket browser_socket_;
  CancelableSyncSocket renderer_socket_;
  DISALLOW_COPY_AND_ASSIGN(AudioOutputDeviceTest);
};
int AudioOutputDeviceTest::CalculateMemorySize() {
  
  int output_memory_size =
      AudioBus::CalculateMemorySize(default_audio_parameters_);
  int frames = default_audio_parameters_.frames_per_buffer();
  int input_memory_size =
      AudioBus::CalculateMemorySize(input_channels_, frames);
  return output_memory_size + input_memory_size;
}
AudioOutputDeviceTest::AudioOutputDeviceTest()
    : synchronized_io_(GetParam()),
      input_channels_(synchronized_io_ ? 2 : 0) {
  default_audio_parameters_.Reset(
      AudioParameters::AUDIO_PCM_LINEAR,
      CHANNEL_LAYOUT_STEREO, 2, input_channels_,
      48000, 16, 1024);
  audio_output_ipc_ = new MockAudioOutputIPC();
  audio_device_ = new AudioOutputDevice(
      scoped_ptr<AudioOutputIPC>(audio_output_ipc_),
      io_loop_.message_loop_proxy());
  audio_device_->Initialize(default_audio_parameters_,
                            &callback_);
  io_loop_.RunUntilIdle();
}
AudioOutputDeviceTest::~AudioOutputDeviceTest() {
  audio_device_ = NULL;
}
void AudioOutputDeviceTest::StartAudioDevice() {
  audio_device_->Start();
  EXPECT_CALL(*audio_output_ipc_, CreateStream(audio_device_.get(), _, 0));
  io_loop_.RunUntilIdle();
}
void AudioOutputDeviceTest::CreateStream() {
  const int kMemorySize = CalculateMemorySize();
  ASSERT_TRUE(shared_memory_.CreateAndMapAnonymous(kMemorySize));
  memset(shared_memory_.memory(), 0xff, kMemorySize);
  ASSERT_TRUE(CancelableSyncSocket::CreatePair(&browser_socket_,
                                               &renderer_socket_));
  
  
  
  SyncSocket::Handle audio_device_socket = SyncSocket::kInvalidHandle;
  ASSERT_TRUE(DuplicateSocketHandle(renderer_socket_.handle(),
                                    &audio_device_socket));
  base::SharedMemoryHandle duplicated_memory_handle;
  ASSERT_TRUE(shared_memory_.ShareToProcess(base::GetCurrentProcessHandle(),
                                            &duplicated_memory_handle));
  audio_device_->OnStreamCreated(duplicated_memory_handle, audio_device_socket,
                                 kMemorySize);
  io_loop_.RunUntilIdle();
}
void AudioOutputDeviceTest::ExpectRenderCallback() {
  
  
  
  
  const int kMemorySize = CalculateMemorySize();
  EXPECT_CALL(*audio_output_ipc_, PlayStream())
      .WillOnce(SendPendingBytes(&browser_socket_, kMemorySize));
  
  
  
  
  
  
  
  if (synchronized_io_) {
    
    EXPECT_CALL(callback_, RenderIO(_, _, _))
        .WillOnce(QuitLoop(io_loop_.message_loop_proxy()));
  } else {
    
    const int kNumberOfFramesToProcess = 0;
    EXPECT_CALL(callback_, Render(_, _))
        .WillOnce(DoAll(
            QuitLoop(io_loop_.message_loop_proxy()),
            Return(kNumberOfFramesToProcess)));
  }
}
void AudioOutputDeviceTest::WaitUntilRenderCallback() {
  
  io_loop_.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(),
                           TestTimeouts::action_timeout());
  io_loop_.Run();
}
void AudioOutputDeviceTest::StopAudioDevice() {
  audio_device_->Stop();
  EXPECT_CALL(*audio_output_ipc_, CloseStream());
  io_loop_.RunUntilIdle();
}
TEST_P(AudioOutputDeviceTest, Initialize) {
  
  
}
TEST_P(AudioOutputDeviceTest, StartStop) {
  StartAudioDevice();
  StopAudioDevice();
}
TEST_P(AudioOutputDeviceTest, StartStopStartStop) {
  StartAudioDevice();
  StopAudioDevice();
  StartAudioDevice();
  StopAudioDevice();
}
TEST_P(AudioOutputDeviceTest, StopBeforeRender) {
  StartAudioDevice();
  
  audio_device_->Stop();
  
  
  EXPECT_CALL(*audio_output_ipc_, CloseStream());
  CreateStream();
}
TEST_P(AudioOutputDeviceTest, CreateStream) {
  StartAudioDevice();
  ExpectRenderCallback();
  CreateStream();
  WaitUntilRenderCallback();
  StopAudioDevice();
}
INSTANTIATE_TEST_CASE_P(Render, AudioOutputDeviceTest, Values(false));
INSTANTIATE_TEST_CASE_P(RenderIO, AudioOutputDeviceTest, Values(true));
}