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#ifndef CONTENT_TEST_WEBRTC_AUDIO_DEVICE_TEST_H_
6#define CONTENT_TEST_WEBRTC_AUDIO_DEVICE_TEST_H_
7
8#include <string>
9
10#include "base/files/file_path.h"
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/message_loop/message_loop.h"
14#include "content/browser/renderer_host/media/mock_media_observer.h"
15#include "content/public/renderer/content_renderer_client.h"
16#include "ipc/ipc_listener.h"
17#include "media/base/audio_hardware_config.h"
18#include "media/base/channel_layout.h"
19#include "testing/gtest/include/gtest/gtest.h"
20#include "third_party/webrtc/common_types.h"
21
22namespace IPC {
23class Channel;
24}
25
26namespace media {
27class AudioManager;
28}
29
30namespace net {
31class URLRequestContext;
32}
33
34namespace webrtc {
35class VoENetwork;
36}
37
38#if defined(OS_WIN)
39namespace base {
40namespace win {
41class ScopedCOMInitializer;
42}
43}
44#endif
45
46namespace content {
47
48class AudioInputRendererHost;
49class AudioMirroringManager;
50class AudioRendererHost;
51class ContentRendererClient;
52class MediaStreamManager;
53class RenderThreadImpl;
54class ResourceContext;
55class TestBrowserThread;
56class WebRTCMockRenderProcess;
57
58// Scoped class for WebRTC interfaces.  Fetches the wrapped interface
59// in the constructor via WebRTC's GetInterface mechanism and then releases
60// the reference in the destructor.
61template<typename T>
62class ScopedWebRTCPtr {
63 public:
64  template<typename Engine>
65  explicit ScopedWebRTCPtr(Engine* e)
66      : ptr_(T::GetInterface(e)) {}
67  explicit ScopedWebRTCPtr(T* p) : ptr_(p) {}
68  ~ScopedWebRTCPtr() { reset(); }
69  T* operator->() const { return ptr_; }
70  T* get() const { return ptr_; }
71
72  // Releases the current pointer.
73  void reset() {
74    if (ptr_) {
75      ptr_->Release();
76      ptr_ = NULL;
77    }
78  }
79
80  bool valid() const { return ptr_ != NULL; }
81
82 private:
83  T* ptr_;
84};
85
86// Wrapper to automatically calling T::Delete in the destructor.
87// This is useful for some WebRTC objects that have their own Create/Delete
88// methods and we can't use our our scoped_* classes.
89template <typename T>
90class WebRTCAutoDelete {
91 public:
92  WebRTCAutoDelete() : ptr_(NULL) {}
93  explicit WebRTCAutoDelete(T* ptr) : ptr_(ptr) {}
94  ~WebRTCAutoDelete() { reset(); }
95
96  void reset() {
97    if (ptr_) {
98      T::Delete(ptr_);
99      ptr_ = NULL;
100    }
101  }
102
103  T* operator->() { return ptr_; }
104  T* get() const { return ptr_; }
105
106  bool valid() const { return ptr_ != NULL; }
107
108 protected:
109  T* ptr_;
110};
111
112// Implemented and defined in the cc file.
113class ReplaceContentClientRenderer;
114
115// Temporarily disabled in LeakSanitizer builds due to memory leaks.
116// http://crbug.com/148865
117#if defined(LEAK_SANITIZER)
118#define MAYBE_WebRTCAudioDeviceTest DISABLED_WebRTCAudioDeviceTest
119#else
120#define MAYBE_WebRTCAudioDeviceTest WebRTCAudioDeviceTest
121#endif
122
123class MAYBE_WebRTCAudioDeviceTest : public ::testing::Test,
124                                    public IPC::Listener {
125 public:
126  MAYBE_WebRTCAudioDeviceTest();
127  virtual ~MAYBE_WebRTCAudioDeviceTest();
128
129  virtual void SetUp() OVERRIDE;
130  virtual void TearDown() OVERRIDE;
131
132  // Sends an IPC message to the IO thread channel.
133  bool Send(IPC::Message* message);
134
135  void SetAudioHardwareConfig(media::AudioHardwareConfig* hardware_config);
136
137 protected:
138  void InitializeIOThread(const char* thread_name);
139  void UninitializeIOThread();
140  void CreateChannel(const char* name);
141  void DestroyChannel();
142
143  void OnGetAudioHardwareConfig(media::AudioParameters* input_params,
144                                media::AudioParameters* output_params);
145
146  // IPC::Listener implementation.
147  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
148
149  // Posts a final task to the IO message loop and waits for completion.
150  void WaitForIOThreadCompletion();
151  void WaitForAudioManagerCompletion();
152  void WaitForMessageLoopCompletion(base::MessageLoopProxy* loop);
153
154  // Convenience getter for gmock.
155  MockMediaInternals& media_observer() const {
156    return *media_internals_.get();
157  }
158
159  std::string GetTestDataPath(const base::FilePath::StringType& file_name);
160
161  scoped_ptr<ReplaceContentClientRenderer> saved_content_renderer_;
162  base::MessageLoopForUI message_loop_;
163  ContentRendererClient content_renderer_client_;
164  RenderThreadImpl* render_thread_;  // Owned by mock_process_.
165  scoped_ptr<WebRTCMockRenderProcess> mock_process_;
166  scoped_ptr<MockMediaInternals> media_internals_;
167  scoped_ptr<MediaStreamManager> media_stream_manager_;
168  scoped_ptr<media::AudioManager> audio_manager_;
169  scoped_ptr<AudioMirroringManager> mirroring_manager_;
170  scoped_ptr<net::URLRequestContext> test_request_context_;
171  scoped_ptr<ResourceContext> resource_context_;
172  scoped_ptr<IPC::Channel> channel_;
173  scoped_refptr<AudioRendererHost> audio_render_host_;
174  scoped_refptr<AudioInputRendererHost> audio_input_renderer_host_;
175
176  media::AudioHardwareConfig* audio_hardware_config_;  // Weak reference.
177
178  // Initialized on the main test thread that we mark as the UI thread.
179  scoped_ptr<TestBrowserThread> ui_thread_;
180  // Initialized on our IO thread to satisfy BrowserThread::IO checks.
181  scoped_ptr<TestBrowserThread> io_thread_;
182
183#if defined(OS_WIN)
184  // COM initialization on the IO thread.
185  scoped_ptr<base::win::ScopedCOMInitializer> initialize_com_;
186#endif
187
188  // These are initialized when we set up our IO thread.
189  bool has_input_devices_;
190  bool has_output_devices_;
191
192  // The previous state for whether sandbox support was enabled in
193  // RenderViewWebKitPlatformSupportImpl.
194  bool sandbox_was_enabled_;
195};
196
197// A very basic implementation of webrtc::Transport that acts as a transport
198// but just forwards all calls to a local webrtc::VoENetwork implementation.
199// Ownership of the VoENetwork object lies outside the class.
200class WebRTCTransportImpl : public webrtc::Transport {
201 public:
202  explicit WebRTCTransportImpl(webrtc::VoENetwork* network);
203  virtual ~WebRTCTransportImpl();
204
205  virtual int SendPacket(int channel, const void* data, int len) OVERRIDE;
206  virtual int SendRTCPPacket(int channel, const void* data, int len) OVERRIDE;
207
208 private:
209  webrtc::VoENetwork* network_;
210};
211
212}  // namespace content
213
214#endif  // CONTENT_TEST_WEBRTC_AUDIO_DEVICE_TEST_H_
215