blob: 2df85c4bf46f4adb2f03196f2487287ab9a31d56 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2013 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
11// This file contains Macros for creating proxies for webrtc MediaStream and
12// PeerConnection classes.
13
14//
15// Example usage:
16//
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000017// class TestInterface : public rtc::RefCountInterface {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000018// public:
19// std::string FooA() = 0;
20// std::string FooB(bool arg1) const = 0;
nisse72c8d2b2016-04-15 03:49:07 -070021// std::string FooC(bool arg1) = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000022// };
23//
24// Note that return types can not be a const reference.
25//
26// class Test : public TestInterface {
27// ... implementation of the interface.
28// };
29//
30// BEGIN_PROXY_MAP(Test)
31// PROXY_METHOD0(std::string, FooA)
32// PROXY_CONSTMETHOD1(std::string, FooB, arg1)
nisse72c8d2b2016-04-15 03:49:07 -070033// PROXY_WORKER_METHOD1(std::string, FooC, arg1)
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034// END_PROXY()
35//
nisse72c8d2b2016-04-15 03:49:07 -070036// where the first two methods are invoked on the signaling thread,
37// and the third is invoked on the worker thread.
38//
39// The proxy can be created using
40//
41// TestProxy::Create(Thread* signaling_thread, Thread* worker_thread,
42// TestInterface*).
43//
44// The variant defined with BEGIN_SIGNALING_PROXY_MAP is unaware of
45// the worker thread, and invokes all methods on the signaling thread.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046
Henrik Kjellander15583c12016-02-10 10:53:12 +010047#ifndef WEBRTC_API_PROXY_H_
48#define WEBRTC_API_PROXY_H_
henrike@webrtc.org28e20752013-07-10 00:45:36 +000049
kwibergd1fe2812016-04-27 06:47:29 -070050#include <memory>
51
tommi@webrtc.org18de6f92014-11-04 12:08:48 +000052#include "webrtc/base/event.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000053#include "webrtc/base/thread.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054
55namespace webrtc {
56
57template <typename R>
58class ReturnType {
59 public:
60 template<typename C, typename M>
61 void Invoke(C* c, M m) { r_ = (c->*m)(); }
62 template<typename C, typename M, typename T1>
63 void Invoke(C* c, M m, T1 a1) { r_ = (c->*m)(a1); }
64 template<typename C, typename M, typename T1, typename T2>
65 void Invoke(C* c, M m, T1 a1, T2 a2) { r_ = (c->*m)(a1, a2); }
66 template<typename C, typename M, typename T1, typename T2, typename T3>
67 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3) { r_ = (c->*m)(a1, a2, a3); }
perkj@webrtc.org81134d02015-01-12 08:30:16 +000068 template<typename C, typename M, typename T1, typename T2, typename T3,
69 typename T4>
70 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3, T4 a4) {
71 r_ = (c->*m)(a1, a2, a3, a4);
72 }
73 template<typename C, typename M, typename T1, typename T2, typename T3,
74 typename T4, typename T5>
75 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
76 r_ = (c->*m)(a1, a2, a3, a4, a5);
77 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078
79 R value() { return r_; }
80
81 private:
82 R r_;
83};
84
85template <>
86class ReturnType<void> {
87 public:
88 template<typename C, typename M>
89 void Invoke(C* c, M m) { (c->*m)(); }
90 template<typename C, typename M, typename T1>
91 void Invoke(C* c, M m, T1 a1) { (c->*m)(a1); }
92 template<typename C, typename M, typename T1, typename T2>
93 void Invoke(C* c, M m, T1 a1, T2 a2) { (c->*m)(a1, a2); }
94 template<typename C, typename M, typename T1, typename T2, typename T3>
95 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3) { (c->*m)(a1, a2, a3); }
96
97 void value() {}
98};
99
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000100namespace internal {
101
102class SynchronousMethodCall
103 : public rtc::MessageData,
104 public rtc::MessageHandler {
105 public:
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000106 explicit SynchronousMethodCall(rtc::MessageHandler* proxy)
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000107 : e_(), proxy_(proxy) {}
108 ~SynchronousMethodCall() {}
109
110 void Invoke(rtc::Thread* t) {
111 if (t->IsCurrent()) {
112 proxy_->OnMessage(NULL);
113 } else {
114 e_.reset(new rtc::Event(false, false));
115 t->Post(this, 0);
andresp@webrtc.org53d90122015-02-09 14:19:09 +0000116 e_->Wait(rtc::Event::kForever);
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000117 }
118 }
119
120 private:
121 void OnMessage(rtc::Message*) { proxy_->OnMessage(NULL); e_->Set(); }
kwibergd1fe2812016-04-27 06:47:29 -0700122 std::unique_ptr<rtc::Event> e_;
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000123 rtc::MessageHandler* proxy_;
124};
125
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000126} // namespace internal
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000127
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000128template <typename C, typename R>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000129class MethodCall0 : public rtc::Message,
130 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000131 public:
132 typedef R (C::*Method)();
133 MethodCall0(C* c, Method m) : c_(c), m_(m) {}
134
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000135 R Marshal(rtc::Thread* t) {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000136 internal::SynchronousMethodCall(this).Invoke(t);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000137 return r_.value();
138 }
139
140 private:
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000141 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000142
143 C* c_;
144 Method m_;
145 ReturnType<R> r_;
146};
147
148template <typename C, typename R>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000149class ConstMethodCall0 : public rtc::Message,
150 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000151 public:
152 typedef R (C::*Method)() const;
153 ConstMethodCall0(C* c, Method m) : c_(c), m_(m) {}
154
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000155 R Marshal(rtc::Thread* t) {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000156 internal::SynchronousMethodCall(this).Invoke(t);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000157 return r_.value();
158 }
159
160 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000161 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000162
163 C* c_;
164 Method m_;
165 ReturnType<R> r_;
166};
167
168template <typename C, typename R, typename T1>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000169class MethodCall1 : public rtc::Message,
170 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000171 public:
172 typedef R (C::*Method)(T1 a1);
173 MethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(a1) {}
174
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000175 R Marshal(rtc::Thread* t) {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000176 internal::SynchronousMethodCall(this).Invoke(t);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000177 return r_.value();
178 }
179
180 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000181 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000182
183 C* c_;
184 Method m_;
185 ReturnType<R> r_;
186 T1 a1_;
187};
188
189template <typename C, typename R, typename T1>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000190class ConstMethodCall1 : public rtc::Message,
191 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000192 public:
193 typedef R (C::*Method)(T1 a1) const;
194 ConstMethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(a1) {}
195
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000196 R Marshal(rtc::Thread* t) {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000197 internal::SynchronousMethodCall(this).Invoke(t);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000198 return r_.value();
199 }
200
201 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000202 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000203
204 C* c_;
205 Method m_;
206 ReturnType<R> r_;
207 T1 a1_;
208};
209
210template <typename C, typename R, typename T1, typename T2>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000211class MethodCall2 : public rtc::Message,
212 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000213 public:
214 typedef R (C::*Method)(T1 a1, T2 a2);
215 MethodCall2(C* c, Method m, T1 a1, T2 a2) : c_(c), m_(m), a1_(a1), a2_(a2) {}
216
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000217 R Marshal(rtc::Thread* t) {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000218 internal::SynchronousMethodCall(this).Invoke(t);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000219 return r_.value();
220 }
221
222 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000223 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_, a2_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000224
225 C* c_;
226 Method m_;
227 ReturnType<R> r_;
228 T1 a1_;
229 T2 a2_;
230};
231
232template <typename C, typename R, typename T1, typename T2, typename T3>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000233class MethodCall3 : public rtc::Message,
234 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235 public:
236 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3);
237 MethodCall3(C* c, Method m, T1 a1, T2 a2, T3 a3)
238 : c_(c), m_(m), a1_(a1), a2_(a2), a3_(a3) {}
239
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000240 R Marshal(rtc::Thread* t) {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000241 internal::SynchronousMethodCall(this).Invoke(t);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000242 return r_.value();
243 }
244
245 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000246 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_, a2_, a3_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000247
248 C* c_;
249 Method m_;
250 ReturnType<R> r_;
251 T1 a1_;
252 T2 a2_;
253 T3 a3_;
254};
255
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000256template <typename C, typename R, typename T1, typename T2, typename T3,
257 typename T4>
258class MethodCall4 : public rtc::Message,
259 public rtc::MessageHandler {
260 public:
261 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3, T4 a4);
262 MethodCall4(C* c, Method m, T1 a1, T2 a2, T3 a3, T4 a4)
263 : c_(c), m_(m), a1_(a1), a2_(a2), a3_(a3), a4_(a4) {}
264
265 R Marshal(rtc::Thread* t) {
266 internal::SynchronousMethodCall(this).Invoke(t);
267 return r_.value();
268 }
269
270 private:
271 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_, a2_, a3_, a4_); }
272
273 C* c_;
274 Method m_;
275 ReturnType<R> r_;
276 T1 a1_;
277 T2 a2_;
278 T3 a3_;
279 T4 a4_;
280};
281
282template <typename C, typename R, typename T1, typename T2, typename T3,
283 typename T4, typename T5>
284class MethodCall5 : public rtc::Message,
285 public rtc::MessageHandler {
286 public:
287 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
288 MethodCall5(C* c, Method m, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
289 : c_(c), m_(m), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5) {}
290
291 R Marshal(rtc::Thread* t) {
292 internal::SynchronousMethodCall(this).Invoke(t);
293 return r_.value();
294 }
295
296 private:
297 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_, a2_, a3_, a4_, a5_); }
298
299 C* c_;
300 Method m_;
301 ReturnType<R> r_;
302 T1 a1_;
303 T2 a2_;
304 T3 a3_;
305 T4 a4_;
306 T5 a5_;
307};
308
nisse72c8d2b2016-04-15 03:49:07 -0700309#define BEGIN_SIGNALING_PROXY_MAP(c) \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000310 class c##Proxy : public c##Interface { \
311 protected: \
312 typedef c##Interface C; \
nisse5b68ab52016-04-07 07:45:54 -0700313 c##Proxy(rtc::Thread* signaling_thread, C* c) \
314 : signaling_thread_(signaling_thread), c_(c) {} \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000315 ~c##Proxy() { \
nisse72c8d2b2016-04-15 03:49:07 -0700316 MethodCall0<c##Proxy, void> call( \
317 this, &c##Proxy::Release_s); \
nisse5b68ab52016-04-07 07:45:54 -0700318 call.Marshal(signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000319 } \
320 \
321 public: \
nisse5b68ab52016-04-07 07:45:54 -0700322 static rtc::scoped_refptr<C> Create(rtc::Thread* signaling_thread, C* c) { \
nisse72c8d2b2016-04-15 03:49:07 -0700323 return new rtc::RefCountedObject<c##Proxy>( \
324 signaling_thread, c); \
nisse5b68ab52016-04-07 07:45:54 -0700325 }
326
nisse72c8d2b2016-04-15 03:49:07 -0700327#define BEGIN_PROXY_MAP(c) \
nisse5b68ab52016-04-07 07:45:54 -0700328 class c##Proxy : public c##Interface { \
329 protected: \
330 typedef c##Interface C; \
331 c##Proxy(rtc::Thread* signaling_thread, rtc::Thread* worker_thread, C* c) \
332 : signaling_thread_(signaling_thread), \
333 worker_thread_(worker_thread), \
334 c_(c) {} \
335 ~c##Proxy() { \
336 MethodCall0<c##Proxy, void> call(this, &c##Proxy::Release_s); \
337 call.Marshal(signaling_thread_); \
338 } \
339 \
340 public: \
341 static rtc::scoped_refptr<C> Create( \
342 rtc::Thread* signaling_thread, rtc::Thread* worker_thread, C* c) { \
343 return new rtc::RefCountedObject<c##Proxy>( \
344 signaling_thread, worker_thread, c); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000345 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000346
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000347#define PROXY_METHOD0(r, method) \
348 r method() override { \
349 MethodCall0<C, r> call(c_.get(), &C::method); \
nisse5b68ab52016-04-07 07:45:54 -0700350 return call.Marshal(signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000351 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000352
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000353#define PROXY_CONSTMETHOD0(r, method) \
354 r method() const override { \
355 ConstMethodCall0<C, r> call(c_.get(), &C::method); \
nisse5b68ab52016-04-07 07:45:54 -0700356 return call.Marshal(signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000357 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000358
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000359#define PROXY_METHOD1(r, method, t1) \
360 r method(t1 a1) override { \
361 MethodCall1<C, r, t1> call(c_.get(), &C::method, a1); \
nisse5b68ab52016-04-07 07:45:54 -0700362 return call.Marshal(signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000363 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000364
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000365#define PROXY_CONSTMETHOD1(r, method, t1) \
366 r method(t1 a1) const override { \
367 ConstMethodCall1<C, r, t1> call(c_.get(), &C::method, a1); \
nisse5b68ab52016-04-07 07:45:54 -0700368 return call.Marshal(signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000369 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000370
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000371#define PROXY_METHOD2(r, method, t1, t2) \
372 r method(t1 a1, t2 a2) override { \
373 MethodCall2<C, r, t1, t2> call(c_.get(), &C::method, a1, a2); \
nisse5b68ab52016-04-07 07:45:54 -0700374 return call.Marshal(signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000375 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000376
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000377#define PROXY_METHOD3(r, method, t1, t2, t3) \
378 r method(t1 a1, t2 a2, t3 a3) override { \
379 MethodCall3<C, r, t1, t2, t3> call(c_.get(), &C::method, a1, a2, a3); \
nisse5b68ab52016-04-07 07:45:54 -0700380 return call.Marshal(signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000381 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000382
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000383#define PROXY_METHOD4(r, method, t1, t2, t3, t4) \
384 r method(t1 a1, t2 a2, t3 a3, t4 a4) override { \
385 MethodCall4<C, r, t1, t2, t3, t4> call(c_.get(), &C::method, a1, a2, a3, \
386 a4); \
nisse5b68ab52016-04-07 07:45:54 -0700387 return call.Marshal(signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000388 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000389
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000390#define PROXY_METHOD5(r, method, t1, t2, t3, t4, t5) \
391 r method(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) override { \
392 MethodCall5<C, r, t1, t2, t3, t4, t5> call(c_.get(), &C::method, a1, a2, \
393 a3, a4, a5); \
nisse5b68ab52016-04-07 07:45:54 -0700394 return call.Marshal(signaling_thread_); \
395 }
396
397// Define methods which should be invoked on the worker thread.
398#define PROXY_WORKER_METHOD1(r, method, t1) \
399 r method(t1 a1) override { \
400 MethodCall1<C, r, t1> call(c_.get(), &C::method, a1); \
401 return call.Marshal(worker_thread_); \
402 }
403
404#define PROXY_WORKER_METHOD2(r, method, t1, t2) \
405 r method(t1 a1, t2 a2) override { \
406 MethodCall2<C, r, t1, t2> call(c_.get(), &C::method, a1, a2); \
407 return call.Marshal(worker_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000408 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000409
nisse72c8d2b2016-04-15 03:49:07 -0700410#define END_SIGNALING_PROXY() \
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000411 private:\
412 void Release_s() {\
413 c_ = NULL;\
414 }\
nisse5b68ab52016-04-07 07:45:54 -0700415 mutable rtc::Thread* signaling_thread_;\
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000416 rtc::scoped_refptr<C> c_;\
nisse72c8d2b2016-04-15 03:49:07 -0700417 };
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000418
nisse72c8d2b2016-04-15 03:49:07 -0700419#define END_PROXY() \
nisse5b68ab52016-04-07 07:45:54 -0700420 private: \
421 void Release_s() { \
422 c_ = NULL; \
423 } \
424 mutable rtc::Thread* signaling_thread_; \
425 mutable rtc::Thread* worker_thread_; \
426 rtc::scoped_refptr<C> c_; \
427 }; \
428
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000429} // namespace webrtc
430
Henrik Kjellander15583c12016-02-10 10:53:12 +0100431#endif // WEBRTC_API_PROXY_H_