summaryrefslogtreecommitdiffstats
path: root/content/test/webrtc_audio_device_test.h
blob: 791ebf51c53594587f9eec33d761c530a9b09ff5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_TEST_WEBRTC_AUDIO_DEVICE_TEST_H_
#define CONTENT_TEST_WEBRTC_AUDIO_DEVICE_TEST_H_

#include <string>

#include "base/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "content/browser/renderer_host/media/mock_media_observer.h"
#include "content/public/renderer/content_renderer_client.h"
#include "media/base/channel_layout.h"
#include "ipc/ipc_channel.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/webrtc/common_types.h"

class AudioInputRendererHost;
class AudioRendererHost;

namespace media {
class AudioManager;
}

namespace media_stream {
class MediaStreamManager;
}

namespace net {
class URLRequestContext;
}

namespace webrtc {
class VoENetwork;
}

#if defined(OS_WIN)
namespace base {
namespace win {
class ScopedCOMInitializer;
}
}
#endif

namespace content {
class ContentRendererClient;
class MockResourceContext;
class RenderThreadImpl;
class ResourceContext;
class TestBrowserThread;
class WebRTCMockRenderProcess;

// Scoped class for WebRTC interfaces.  Fetches the wrapped interface
// in the constructor via WebRTC's GetInterface mechanism and then releases
// the reference in the destructor.
template<typename T>
class ScopedWebRTCPtr {
 public:
  template<typename Engine>
  explicit ScopedWebRTCPtr(Engine* e)
      : ptr_(T::GetInterface(e)) {}
  explicit ScopedWebRTCPtr(T* p) : ptr_(p) {}
  ~ScopedWebRTCPtr() { reset(); }
  T* operator->() const { return ptr_; }
  T* get() const { return ptr_; }

  // Releases the current pointer.
  void reset() {
    if (ptr_) {
      ptr_->Release();
      ptr_ = NULL;
    }
  }

  bool valid() const { return ptr_ != NULL; }

 private:
  T* ptr_;
};

// Wrapper to automatically calling T::Delete in the destructor.
// This is useful for some WebRTC objects that have their own Create/Delete
// methods and we can't use our our scoped_* classes.
template <typename T>
class WebRTCAutoDelete {
 public:
  WebRTCAutoDelete() : ptr_(NULL) {}
  explicit WebRTCAutoDelete(T* ptr) : ptr_(ptr) {}
  ~WebRTCAutoDelete() { reset(); }

  void reset() {
    if (ptr_) {
      T::Delete(ptr_);
      ptr_ = NULL;
    }
  }

  T* operator->() { return ptr_; }
  T* get() const { return ptr_; }

  bool valid() const { return ptr_ != NULL; }

 protected:
  T* ptr_;
};

// Individual tests can provide an implementation (or mock) of this interface
// when the audio code queries for hardware capabilities on the IO thread.
class AudioUtilInterface {
 public:
  virtual ~AudioUtilInterface() {}
  virtual int GetAudioHardwareSampleRate() = 0;
  virtual int GetAudioInputHardwareSampleRate(
      const std::string& device_id) = 0;
  virtual media::ChannelLayout GetAudioInputHardwareChannelLayout(
      const std::string& device_id) = 0;
};

// Implemented and defined in the cc file.
class ReplaceContentClientRenderer;

class WebRTCAudioDeviceTest : public ::testing::Test, public IPC::Listener {
 public:
  WebRTCAudioDeviceTest();
  virtual ~WebRTCAudioDeviceTest();

  virtual void SetUp() OVERRIDE;
  virtual void TearDown() OVERRIDE;

  // Sends an IPC message to the IO thread channel.
  bool Send(IPC::Message* message);

  void SetAudioUtilCallback(AudioUtilInterface* callback);

 protected:
  void InitializeIOThread(const char* thread_name);
  void UninitializeIOThread();
  void CreateChannel(const char* name);
  void DestroyChannel();

  void OnGetHardwareSampleRate(int* sample_rate);
  void OnGetHardwareInputSampleRate(int* sample_rate);
  void OnGetHardwareInputChannelLayout(media::ChannelLayout* channels);

  // IPC::Listener implementation.
  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;

  // Posts a final task to the IO message loop and waits for completion.
  void WaitForIOThreadCompletion();
  void WaitForAudioManagerCompletion();
  void WaitForMessageLoopCompletion(base::MessageLoopProxy* loop);

  // Convenience getter for gmock.
  MockMediaObserver& media_observer() const {
    return *media_observer_.get();
  }

  std::string GetTestDataPath(const FilePath::StringType& file_name);

  scoped_ptr<ReplaceContentClientRenderer> saved_content_renderer_;
  MessageLoopForUI message_loop_;
  content::ContentRendererClient content_renderer_client_;
  RenderThreadImpl* render_thread_;  // Owned by mock_process_.
  scoped_ptr<WebRTCMockRenderProcess> mock_process_;
  scoped_ptr<MockMediaObserver> media_observer_;
  scoped_ptr<media_stream::MediaStreamManager> media_stream_manager_;
  scoped_ptr<media::AudioManager> audio_manager_;
  scoped_ptr<net::URLRequestContext> test_request_context_;
  scoped_ptr<content::ResourceContext> resource_context_;
  scoped_ptr<IPC::Channel> channel_;
  scoped_refptr<AudioRendererHost> audio_render_host_;
  scoped_refptr<AudioInputRendererHost> audio_input_renderer_host_;

  AudioUtilInterface* audio_util_callback_;  // Weak reference.

  // Initialized on the main test thread that we mark as the UI thread.
  scoped_ptr<content::TestBrowserThread> ui_thread_;
  // Initialized on our IO thread to satisfy BrowserThread::IO checks.
  scoped_ptr<content::TestBrowserThread> io_thread_;

#if defined(OS_WIN)
  // COM initialization on the IO thread.
  scoped_ptr<base::win::ScopedCOMInitializer> initialize_com_;
#endif

  // These are initialized when we set up our IO thread.
  bool has_input_devices_;
  bool has_output_devices_;

  // The previous state for whether sandbox support was enabled in
  // RenderViewWebKitPlatformSupportImpl.
  bool sandbox_was_enabled_;
};

// A very basic implementation of webrtc::Transport that acts as a transport
// but just forwards all calls to a local webrtc::VoENetwork implementation.
// Ownership of the VoENetwork object lies outside the class.
class WebRTCTransportImpl : public webrtc::Transport {
 public:
  explicit WebRTCTransportImpl(webrtc::VoENetwork* network);
  virtual ~WebRTCTransportImpl();

  virtual int SendPacket(int channel, const void* data, int len) OVERRIDE;
  virtual int SendRTCPPacket(int channel, const void* data, int len) OVERRIDE;

 private:
  webrtc::VoENetwork* network_;
};

}  // namespace content

#endif  // CONTENT_TEST_WEBRTC_AUDIO_DEVICE_TEST_H_