Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: components/devtools_bridge/session_dependency_factory.cc

Issue 1142463003: Remove devtools_bridge component (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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 "components/devtools_bridge/session_dependency_factory.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/task_runner.h"
10 #include "base/threading/thread.h"
11 #include "components/devtools_bridge/abstract_data_channel.h"
12 #include "components/devtools_bridge/abstract_peer_connection.h"
13 #include "components/devtools_bridge/rtc_configuration.h"
14 #include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface .h"
15 #include "third_party/libjingle/source/talk/app/webrtc/peerconnectioninterface.h "
16 #include "third_party/webrtc/base/bind.h"
17 #include "third_party/webrtc/base/messagehandler.h"
18 #include "third_party/webrtc/base/messagequeue.h"
19 #include "third_party/webrtc/base/ssladapter.h"
20 #include "third_party/webrtc/base/thread.h"
21
22 namespace devtools_bridge {
23
24 class RTCConfiguration::Impl
25 : public RTCConfiguration,
26 public webrtc::PeerConnectionInterface::RTCConfiguration {
27 public:
28 void AddIceServer(const std::string& uri,
29 const std::string& username,
30 const std::string& credential) override {
31 webrtc::PeerConnectionInterface::IceServer server;
32 server.uri = uri;
33 server.username = username;
34 server.password = credential;
35 servers.push_back(server);
36 }
37
38 const Impl& impl() const override {
39 return *this;
40 }
41
42 private:
43 webrtc::PeerConnectionInterface::RTCConfiguration base_;
44 };
45
46 namespace {
47
48 template <typename T>
49 void CheckedRelease(rtc::scoped_refptr<T>* ptr) {
50 CHECK_EQ(0, ptr->release()->Release());
51 }
52
53 class MediaConstraints
54 : public webrtc::MediaConstraintsInterface {
55 public:
56 ~MediaConstraints() override {}
57
58 const Constraints& GetMandatory() const override { return mandatory_; }
59
60 const Constraints& GetOptional() const override { return optional_; }
61
62 void AddMandatory(const std::string& key, const std::string& value) {
63 mandatory_.push_back(Constraint(key, value));
64 }
65
66 private:
67 Constraints mandatory_;
68 Constraints optional_;
69 };
70
71 /**
72 * Posts tasks on signaling thread. If stopped (when SesseionDependencyFactry
73 * is destroying) ignores posted tasks.
74 */
75 class SignalingThreadTaskRunner : public base::TaskRunner,
76 private rtc::MessageHandler {
77 public:
78 explicit SignalingThreadTaskRunner(rtc::Thread* thread) : thread_(thread) {}
79
80 bool PostDelayedTask(const tracked_objects::Location& from_here,
81 const base::Closure& task,
82 base::TimeDelta delay) override {
83 DCHECK(delay.ToInternalValue() == 0);
84
85 rtc::CritScope scope(&critical_section_);
86
87 if (thread_)
88 thread_->Send(this, 0, new Task(task));
89
90 return true;
91 }
92
93 bool RunsTasksOnCurrentThread() const override {
94 rtc::CritScope scope(&critical_section_);
95
96 return thread_ != NULL && thread_->IsCurrent();
97 }
98
99 void Stop() {
100 rtc::CritScope scope(&critical_section_);
101 thread_ = NULL;
102 }
103
104 private:
105 typedef rtc::TypedMessageData<base::Closure> Task;
106
107 ~SignalingThreadTaskRunner() override {}
108
109 void OnMessage(rtc::Message* msg) override {
110 static_cast<Task*>(msg->pdata)->data().Run();
111 }
112
113 mutable rtc::CriticalSection critical_section_;
114 rtc::Thread* thread_; // Guarded by |critical_section_|.
115 };
116
117 class DataChannelObserverImpl : public webrtc::DataChannelObserver {
118 public:
119 DataChannelObserverImpl(
120 webrtc::DataChannelInterface* data_channel,
121 scoped_ptr<AbstractDataChannel::Observer> observer)
122 : data_channel_(data_channel),
123 observer_(observer.Pass()) {
124 }
125
126 void InitState() {
127 open_ = data_channel_->state() == webrtc::DataChannelInterface::kOpen;
128 }
129
130 void OnStateChange() override {
131 bool open = data_channel_->state() == webrtc::DataChannelInterface::kOpen;
132
133 if (open == open_) return;
134
135 open_ = open;
136 if (open) {
137 observer_->OnOpen();
138 } else {
139 observer_->OnClose();
140 }
141 }
142
143 void OnMessage(const webrtc::DataBuffer& buffer) override {
144 observer_->OnMessage(buffer.data.data(), buffer.size());
145 }
146
147 private:
148 webrtc::DataChannelInterface* const data_channel_;
149 scoped_ptr<AbstractDataChannel::Observer> const observer_;
150 bool open_;
151 };
152
153 /**
154 * Thread-safe view on AbstractDataChannel.
155 */
156 class DataChannelProxyImpl : public AbstractDataChannel::Proxy {
157 public:
158 DataChannelProxyImpl(
159 SessionDependencyFactory* factory,
160 rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel)
161 : data_channel_(data_channel),
162 signaling_thread_task_runner_(
163 factory->signaling_thread_task_runner()) {
164 }
165
166 void StopOnSignalingThread() {
167 data_channel_ = NULL;
168 }
169
170 void SendBinaryMessage(const void* data, size_t length) override {
171 auto buffer = make_scoped_ptr(new webrtc::DataBuffer(rtc::Buffer(), true));
172 buffer->data.SetData(static_cast<const uint8_t*>(data), length);
173
174 signaling_thread_task_runner_->PostTask(
175 FROM_HERE, base::Bind(
176 &DataChannelProxyImpl::SendMessageOnSignalingThread,
177 this,
178 base::Passed(&buffer)));
179 }
180
181 void Close() override {
182 signaling_thread_task_runner_->PostTask(
183 FROM_HERE, base::Bind(&DataChannelProxyImpl::CloseOnSignalingThread,
184 this));
185 }
186
187 private:
188
189 ~DataChannelProxyImpl() override {}
190
191 void SendMessageOnSignalingThread(scoped_ptr<webrtc::DataBuffer> message) {
192 if (data_channel_ != NULL)
193 data_channel_->Send(*message);
194 }
195
196 void CloseOnSignalingThread() {
197 if (data_channel_ != NULL)
198 data_channel_->Close();
199 }
200
201 // Accessed on signaling thread.
202 rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel_;
203
204 const scoped_refptr<base::TaskRunner> signaling_thread_task_runner_;
205 };
206
207 class DataChannelImpl : public AbstractDataChannel {
208 public:
209 DataChannelImpl(
210 SessionDependencyFactory* factory,
211 rtc::Thread* const signaling_thread,
212 rtc::scoped_refptr<webrtc::DataChannelInterface> impl)
213 : factory_(factory),
214 signaling_thread_(signaling_thread),
215 impl_(impl) {
216 }
217
218 ~DataChannelImpl() override {
219 if (proxy_.get()) {
220 signaling_thread_->Invoke<void>(rtc::Bind(
221 &DataChannelProxyImpl::StopOnSignalingThread, proxy_.get()));
222 }
223 }
224
225 void RegisterObserver(scoped_ptr<Observer> observer) override {
226 observer_.reset(new DataChannelObserverImpl(impl_.get(), observer.Pass()));
227 signaling_thread_->Invoke<void>(rtc::Bind(
228 &DataChannelImpl::RegisterObserverOnSignalingThread, this));
229 }
230
231 void UnregisterObserver() override {
232 DCHECK(observer_.get() != NULL);
233 impl_->UnregisterObserver();
234 observer_.reset();
235 }
236
237 void SendBinaryMessage(void* data, size_t length) override {
238 SendMessage(data, length, true);
239 }
240
241 void SendTextMessage(void* data, size_t length) override {
242 SendMessage(data, length, false);
243 }
244
245 void SendMessage(void* data, size_t length, bool is_binary) {
246 impl_->Send(webrtc::DataBuffer(
247 rtc::Buffer(static_cast<uint8_t*>(data), length), is_binary));
248 }
249
250 void Close() override {
251 impl_->Close();
252 }
253
254 scoped_refptr<Proxy> proxy() override {
255 if (!proxy_.get())
256 proxy_ = new DataChannelProxyImpl(factory_, impl_);
257 return proxy_;
258 }
259
260 private:
261 void RegisterObserverOnSignalingThread() {
262 // State initialization and observer registration happen atomically
263 // if done on the signaling thread (see rtc::Thread::Send).
264 observer_->InitState();
265 impl_->RegisterObserver(observer_.get());
266 }
267
268 SessionDependencyFactory* const factory_;
269 scoped_refptr<DataChannelProxyImpl> proxy_;
270 rtc::Thread* const signaling_thread_;
271 scoped_ptr<DataChannelObserverImpl> observer_;
272 const rtc::scoped_refptr<webrtc::DataChannelInterface> impl_;
273 };
274
275 class PeerConnectionObserverImpl
276 : public webrtc::PeerConnectionObserver {
277 public:
278 PeerConnectionObserverImpl(AbstractPeerConnection::Delegate* delegate)
279 : delegate_(delegate),
280 connected_(false) {
281 }
282
283 void OnAddStream(webrtc::MediaStreamInterface* stream) override {}
284
285 void OnRemoveStream(webrtc::MediaStreamInterface* stream) override {}
286
287 void OnDataChannel(webrtc::DataChannelInterface* data_channel) override {}
288
289 void OnRenegotiationNeeded() override {}
290
291 void OnSignalingChange(
292 webrtc::PeerConnectionInterface::SignalingState new_state) override {}
293
294 void OnIceConnectionChange(
295 webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
296 bool connected =
297 new_state == webrtc::PeerConnectionInterface::kIceConnectionConnected ||
298 new_state == webrtc::PeerConnectionInterface::kIceConnectionCompleted;
299
300 if (connected != connected_) {
301 connected_ = connected;
302 delegate_->OnIceConnectionChange(connected_);
303 }
304 }
305
306 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
307 std::string sdp;
308 candidate->ToString(&sdp);
309
310 delegate_->OnIceCandidate(
311 candidate->sdp_mid(), candidate->sdp_mline_index(), sdp);
312 }
313
314 private:
315 AbstractPeerConnection::Delegate* const delegate_;
316 bool connected_;
317 };
318
319 /**
320 * Helper object which may outlive PeerConnectionImpl. Provides access
321 * to the connection and the delegate to operaion callback objects
322 * in a safe way. Always accessible on the signaling thread.
323 */
324 class PeerConnectionHolder : public rtc::RefCountInterface {
325 public:
326 PeerConnectionHolder(
327 rtc::Thread* signaling_thread,
328 webrtc::PeerConnectionInterface* connection,
329 AbstractPeerConnection::Delegate* delegate)
330 : signaling_thread_(signaling_thread),
331 connection_(connection),
332 delegate_(delegate),
333 disposed_(false) {
334 }
335
336 ~PeerConnectionHolder() override { DCHECK(disposed_); }
337
338 void Dispose() {
339 DCHECK(!IsDisposed());
340 disposed_ = true;
341 }
342
343 webrtc::PeerConnectionInterface* connection() {
344 DCHECK(!IsDisposed());
345 return connection_;
346 }
347
348 AbstractPeerConnection::Delegate* delegate() {
349 DCHECK(!IsDisposed());
350 return delegate_;
351 }
352
353 bool IsDisposed() {
354 DCHECK(signaling_thread_->IsCurrent());
355 return disposed_;
356 }
357
358 private:
359 rtc::Thread* const signaling_thread_;
360 webrtc::PeerConnectionInterface* const connection_;
361 AbstractPeerConnection::Delegate* const delegate_;
362 bool disposed_;
363 };
364
365 class CreateAndSetHandler
366 : public webrtc::CreateSessionDescriptionObserver,
367 public webrtc::SetSessionDescriptionObserver {
368 public:
369 explicit CreateAndSetHandler(
370 rtc::scoped_refptr<PeerConnectionHolder> holder)
371 : holder_(holder) {
372 }
373
374 void OnSuccess(webrtc::SessionDescriptionInterface* desc) override {
375 if (holder_->IsDisposed()) return;
376
377 type_ = desc->type();
378 if (desc->ToString(&description_)) {
379 holder_->connection()->SetLocalDescription(this, desc);
380 } else {
381 OnFailure("Can't serialize session description");
382 }
383 }
384
385 void OnSuccess() override {
386 if (holder_->IsDisposed()) return;
387
388 if (type_ == webrtc::SessionDescriptionInterface::kOffer) {
389 holder_->delegate()->OnLocalOfferCreatedAndSetSet(description_);
390 } else {
391 DCHECK_EQ(webrtc::SessionDescriptionInterface::kAnswer, type_);
392
393 holder_->delegate()->OnLocalAnswerCreatedAndSetSet(description_);
394 }
395 }
396
397 void OnFailure(const std::string& error) override {
398 if (holder_->IsDisposed()) return;
399
400 holder_->delegate()->OnFailure(error);
401 }
402
403 private:
404 const rtc::scoped_refptr<PeerConnectionHolder> holder_;
405 std::string type_;
406 std::string description_;
407 };
408
409 class SetRemoteDescriptionHandler
410 : public webrtc::SetSessionDescriptionObserver {
411 public:
412 SetRemoteDescriptionHandler(
413 rtc::scoped_refptr<PeerConnectionHolder> holder)
414 : holder_(holder) {
415 }
416
417 void OnSuccess() override {
418 if (holder_->IsDisposed()) return;
419
420 holder_->delegate()->OnRemoteDescriptionSet();
421 }
422
423 void OnFailure(const std::string& error) override {
424 if (holder_->IsDisposed()) return;
425
426 holder_->delegate()->OnFailure(error);
427 }
428
429 private:
430 const rtc::scoped_refptr<PeerConnectionHolder> holder_;
431 };
432
433 class PeerConnectionImpl : public AbstractPeerConnection {
434 public:
435 PeerConnectionImpl(
436 SessionDependencyFactory* const factory,
437 rtc::Thread* signaling_thread,
438 rtc::scoped_refptr<webrtc::PeerConnectionInterface> connection,
439 scoped_ptr<PeerConnectionObserverImpl> observer,
440 scoped_ptr<AbstractPeerConnection::Delegate> delegate)
441 : factory_(factory),
442 holder_(new rtc::RefCountedObject<PeerConnectionHolder>(
443 signaling_thread, connection.get(), delegate.get())),
444 signaling_thread_(signaling_thread),
445 connection_(connection),
446 observer_(observer.Pass()),
447 delegate_(delegate.Pass()) {
448 }
449
450 ~PeerConnectionImpl() override {
451 signaling_thread_->Invoke<void>(rtc::Bind(
452 &PeerConnectionImpl::DisposeOnSignalingThread, this));
453 }
454
455 void CreateAndSetLocalOffer() override {
456 connection_->CreateOffer(MakeCreateAndSetHandler(), NULL);
457 }
458
459 void CreateAndSetLocalAnswer() override {
460 connection_->CreateAnswer(MakeCreateAndSetHandler(), NULL);
461 }
462
463 void SetRemoteOffer(const std::string& description) override {
464 SetRemoteDescription(
465 webrtc::SessionDescriptionInterface::kOffer, description);
466 }
467
468 void SetRemoteAnswer(const std::string& description) override {
469 SetRemoteDescription(
470 webrtc::SessionDescriptionInterface::kAnswer, description);
471 }
472
473 void SetRemoteDescription(
474 const std::string& type, const std::string& description) {
475 webrtc::SdpParseError error;
476 scoped_ptr<webrtc::SessionDescriptionInterface> value(
477 webrtc::CreateSessionDescription(type, description, &error));
478 if (value == NULL) {
479 OnParseError(error);
480 return;
481 }
482 // Takes ownership on |value|.
483 connection_->SetRemoteDescription(
484 new rtc::RefCountedObject<SetRemoteDescriptionHandler>(holder_),
485 value.release());
486 }
487
488 void AddIceCandidate(const std::string& sdp_mid,
489 int sdp_mline_index,
490 const std::string& sdp) override {
491 webrtc::SdpParseError error;
492 auto candidate = webrtc::CreateIceCandidate(
493 sdp_mid, sdp_mline_index, sdp, &error);
494 if (candidate == NULL) {
495 OnParseError(error);
496 return;
497 }
498 // Doesn't takes ownership.
499 connection_->AddIceCandidate(candidate);
500 delete candidate;
501 }
502
503 scoped_ptr<AbstractDataChannel> CreateDataChannel(int channelId) override {
504 webrtc::DataChannelInit init;
505 init.ordered = true;
506 init.negotiated = true;
507 init.id = channelId;
508
509 return make_scoped_ptr(new DataChannelImpl(
510 factory_,
511 signaling_thread_,
512 connection_->CreateDataChannel("", &init)));
513 }
514
515 private:
516 webrtc::CreateSessionDescriptionObserver* MakeCreateAndSetHandler() {
517 return new rtc::RefCountedObject<CreateAndSetHandler>(holder_);
518 }
519
520 void DisposeOnSignalingThread() {
521 DCHECK(signaling_thread_->IsCurrent());
522
523 CheckedRelease(&connection_);
524 holder_->Dispose();
525 }
526
527 void OnParseError(const webrtc::SdpParseError& error) {
528 // TODO(serya): Send on signaling thread.
529 }
530
531 SessionDependencyFactory* const factory_;
532 const rtc::scoped_refptr<PeerConnectionHolder> holder_;
533 rtc::Thread* const signaling_thread_;
534 rtc::scoped_refptr<webrtc::PeerConnectionInterface> connection_;
535 const scoped_ptr<PeerConnectionObserverImpl> observer_;
536 const scoped_ptr<AbstractPeerConnection::Delegate> delegate_;
537 };
538
539 class SessionDependencyFactoryImpl : public SessionDependencyFactory {
540 public:
541 SessionDependencyFactoryImpl(
542 const base::Closure& cleanup_on_signaling_thread)
543 : cleanup_on_signaling_thread_(cleanup_on_signaling_thread) {
544 signaling_thread_.SetName("signaling_thread", NULL);
545 signaling_thread_.Start();
546 worker_thread_.SetName("worker_thread", NULL);
547 worker_thread_.Start();
548
549 factory_ = webrtc::CreatePeerConnectionFactory(
550 &worker_thread_, &signaling_thread_, NULL, NULL, NULL);
551 }
552
553 ~SessionDependencyFactoryImpl() override {
554 if (signaling_thread_task_runner_.get())
555 signaling_thread_task_runner_->Stop();
556
557 signaling_thread_.Invoke<void>(rtc::Bind(
558 &SessionDependencyFactoryImpl::DisposeOnSignalingThread, this));
559 }
560
561 scoped_ptr<AbstractPeerConnection> CreatePeerConnection(
562 scoped_ptr<RTCConfiguration> config,
563 scoped_ptr<AbstractPeerConnection::Delegate> delegate) override {
564 auto observer = make_scoped_ptr(
565 new PeerConnectionObserverImpl(delegate.get()));
566
567 MediaConstraints constraints;
568 constraints.AddMandatory(
569 MediaConstraints::kEnableDtlsSrtp, MediaConstraints::kValueTrue);
570
571 auto connection = factory_->CreatePeerConnection(
572 config->impl(), &constraints, NULL, NULL, observer.get());
573
574 return make_scoped_ptr(new PeerConnectionImpl(
575 this, &signaling_thread_, connection, observer.Pass(),
576 delegate.Pass()));
577 }
578
579 scoped_refptr<base::TaskRunner> signaling_thread_task_runner() override {
580 if (!signaling_thread_task_runner_.get()) {
581 signaling_thread_task_runner_ =
582 new SignalingThreadTaskRunner(&signaling_thread_);
583 }
584 return signaling_thread_task_runner_;
585 }
586
587 scoped_refptr<base::TaskRunner> io_thread_task_runner() override {
588 if (!io_thread_.get()) {
589 io_thread_.reset(new base::Thread("devtools bridge IO thread"));
590 base::Thread::Options options;
591 options.message_loop_type = base::MessageLoop::TYPE_IO;
592 CHECK(io_thread_->StartWithOptions(options));
593 }
594 return io_thread_->task_runner();
595 }
596
597 private:
598 void DisposeOnSignalingThread() {
599 DCHECK(signaling_thread_.IsCurrent());
600 CheckedRelease(&factory_);
601 if (!cleanup_on_signaling_thread_.is_null())
602 cleanup_on_signaling_thread_.Run();
603 }
604
605 scoped_ptr<base::Thread> io_thread_;
606 scoped_refptr<SignalingThreadTaskRunner> signaling_thread_task_runner_;
607 base::Closure cleanup_on_signaling_thread_;
608 rtc::Thread signaling_thread_;
609 rtc::Thread worker_thread_;
610 rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> factory_;
611 };
612
613 } // namespace
614
615 // RTCCOnfiguration
616
617 // static
618 scoped_ptr<RTCConfiguration> RTCConfiguration::CreateInstance() {
619 return make_scoped_ptr(new RTCConfiguration::Impl());
620 }
621
622 // SessionDependencyFactory
623
624 // static
625 bool SessionDependencyFactory::InitializeSSL() {
626 return rtc::InitializeSSL();
627 }
628
629 // static
630 bool SessionDependencyFactory::CleanupSSL() {
631 return rtc::CleanupSSL();
632 }
633
634 // static
635 scoped_ptr<SessionDependencyFactory> SessionDependencyFactory::CreateInstance(
636 const base::Closure& cleanup_on_signaling_thread) {
637 return make_scoped_ptr(new SessionDependencyFactoryImpl(
638 cleanup_on_signaling_thread));
639 }
640
641 } // namespace devtools_bridge
OLDNEW
« no previous file with comments | « components/devtools_bridge/session_dependency_factory.h ('k') | components/devtools_bridge/socket_tunnel_connection.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698