• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libjingle
3  * Copyright 2004 Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include <string>
29 #include "talk/media/base/constants.h"
30 #include "talk/media/base/screencastid.h"
31 #include "talk/p2p/base/parsing.h"
32 #include "talk/session/media/call.h"
33 #include "talk/session/media/currentspeakermonitor.h"
34 #include "talk/session/media/mediasessionclient.h"
35 #include "webrtc/base/helpers.h"
36 #include "webrtc/base/logging.h"
37 #include "webrtc/base/thread.h"
38 #include "webrtc/base/window.h"
39 
40 namespace cricket {
41 
42 const uint32 MSG_CHECKAUTODESTROY = 1;
43 const uint32 MSG_TERMINATECALL = 2;
44 const uint32 MSG_PLAYDTMF = 3;
45 
46 namespace {
47 const int kDTMFDelay = 300;  // msec
48 const size_t kMaxDTMFDigits = 30;
49 const int kSendToVoicemailTimeout = 1000*20;
50 const int kNoVoicemailTimeout = 1000*180;
51 const int kMediaMonitorInterval = 1000*15;
52 // In order to be the same as the server-side switching, this must be 100.
53 const int kAudioMonitorPollPeriodMillis = 100;
54 
55 // V is a pointer type.
56 template<class K, class V>
FindOrNull(const std::map<K,V> & map,const K & key)57 V FindOrNull(const std::map<K, V>& map,
58              const K& key) {
59   typename std::map<K, V>::const_iterator it = map.find(key);
60   return (it != map.end()) ? it->second : NULL;
61 }
62 
63 
ContentContainsCrypto(const cricket::ContentInfo * content)64 bool ContentContainsCrypto(const cricket::ContentInfo* content) {
65   if (content != NULL) {
66     const cricket::MediaContentDescription* desc =
67         static_cast<const cricket::MediaContentDescription*>(
68             content->description);
69     if (!desc || desc->cryptos().empty()) {
70       return false;
71     }
72   }
73   return true;
74 }
75 
76 }
77 
AudioSourceProxy(Call * call)78 AudioSourceProxy::AudioSourceProxy(Call* call)
79     : call_(call) {
80   call_->SignalAudioMonitor.connect(this, &AudioSourceProxy::OnAudioMonitor);
81   call_->SignalMediaStreamsUpdate.connect(
82       this, &AudioSourceProxy::OnMediaStreamsUpdate);
83 }
84 
OnAudioMonitor(Call * call,const AudioInfo & info)85 void AudioSourceProxy::OnAudioMonitor(Call* call, const AudioInfo& info) {
86   SignalAudioMonitor(this, info);
87 }
88 
OnMediaStreamsUpdate(Call * call,Session * session,const MediaStreams & added,const MediaStreams & removed)89 void AudioSourceProxy::OnMediaStreamsUpdate(Call* call, Session* session,
90     const MediaStreams& added, const MediaStreams& removed) {
91   SignalMediaStreamsUpdate(this, session, added, removed);
92 }
93 
Call(MediaSessionClient * session_client)94 Call::Call(MediaSessionClient* session_client)
95     : id_(rtc::CreateRandomId()),
96       session_client_(session_client),
97       has_video_(false),
98       has_data_(false),
99       muted_(false),
100       video_muted_(false),
101       send_to_voicemail_(true),
102       playing_dtmf_(false) {
103   audio_source_proxy_.reset(new AudioSourceProxy(this));
104 }
105 
~Call()106 Call::~Call() {
107   while (media_session_map_.begin() != media_session_map_.end()) {
108     Session* session = media_session_map_.begin()->second.session;
109     RemoveSession(session);
110     session_client_->session_manager()->DestroySession(session);
111   }
112   rtc::Thread::Current()->Clear(this);
113 }
114 
InitiateSession(const buzz::Jid & to,const buzz::Jid & initiator,const CallOptions & options)115 Session* Call::InitiateSession(const buzz::Jid& to,
116                                const buzz::Jid& initiator,
117                                const CallOptions& options) {
118   std::string id;
119   std::string initiator_name = initiator.Str();
120   return InternalInitiateSession(id, to, initiator_name, options);
121 }
122 
InitiateSession(const std::string & id,const buzz::Jid & to,const CallOptions & options)123 Session *Call::InitiateSession(const std::string& id,
124                                const buzz::Jid& to,
125                                const CallOptions& options) {
126   std::string initiator_name;
127   return InternalInitiateSession(id, to, initiator_name, options);
128 }
129 
IncomingSession(Session * session,const SessionDescription * offer)130 void Call::IncomingSession(Session* session, const SessionDescription* offer) {
131   AddSession(session, offer);
132 
133   // Make sure the session knows about the incoming ssrcs. This needs to be done
134   // prior to the SignalSessionState call, because that may trigger handling of
135   // these new SSRCs, so they need to be registered before then.
136   UpdateRemoteMediaStreams(session, offer->contents(), false);
137 
138   // Missed the first state, the initiate, which is needed by
139   // call_client.
140   SignalSessionState(this, session, Session::STATE_RECEIVEDINITIATE);
141 }
142 
AcceptSession(Session * session,const cricket::CallOptions & options)143 void Call::AcceptSession(Session* session,
144                          const cricket::CallOptions& options) {
145   MediaSessionMap::iterator it = media_session_map_.find(session->id());
146   if (it != media_session_map_.end()) {
147     const SessionDescription* answer = session_client_->CreateAnswer(
148         session->remote_description(), options);
149     it->second.session->Accept(answer);
150   }
151 }
152 
RejectSession(Session * session)153 void Call::RejectSession(Session* session) {
154   // Assume polite decline.
155   MediaSessionMap::iterator it = media_session_map_.find(session->id());
156   if (it != media_session_map_.end())
157     it->second.session->Reject(STR_TERMINATE_DECLINE);
158 }
159 
TerminateSession(Session * session)160 void Call::TerminateSession(Session* session) {
161   MediaSessionMap::iterator it = media_session_map_.find(session->id());
162   if (it != media_session_map_.end()) {
163     // Assume polite terminations.
164     it->second.session->Terminate();
165   }
166 }
167 
Terminate()168 void Call::Terminate() {
169   // Copy the list so that we can iterate over it in a stable way
170   std::vector<Session*> sessions = this->sessions();
171 
172   // There may be more than one session to terminate
173   std::vector<Session*>::iterator it;
174   for (it = sessions.begin(); it != sessions.end(); ++it) {
175     TerminateSession(*it);
176   }
177 }
178 
SendViewRequest(Session * session,const ViewRequest & view_request)179 bool Call::SendViewRequest(Session* session,
180                            const ViewRequest& view_request) {
181   StaticVideoViews::const_iterator it;
182   for (it = view_request.static_video_views.begin();
183        it != view_request.static_video_views.end(); ++it) {
184     StreamParams found_stream;
185     bool found = false;
186     MediaStreams* recv_streams = GetMediaStreams(session);
187     if (recv_streams)
188       found = recv_streams->GetVideoStream(it->selector, &found_stream);
189     if (!found) {
190       LOG(LS_WARNING) << "Trying to send view request for ("
191                       << it->selector.ssrc << ", '"
192                       << it->selector.groupid << "', '"
193                       << it->selector.streamid << "'"
194                       << ") is not in the local streams.";
195       return false;
196     }
197   }
198 
199   XmlElements elems;
200   WriteError error;
201   if (!WriteJingleViewRequest(CN_VIDEO, view_request, &elems, &error)) {
202     LOG(LS_ERROR) << "Couldn't write out view request: " << error.text;
203     return false;
204   }
205 
206   return session->SendInfoMessage(elems, session->remote_name());
207 }
208 
SetVideoRenderer(Session * session,uint32 ssrc,VideoRenderer * renderer)209 void Call::SetVideoRenderer(Session* session, uint32 ssrc,
210                             VideoRenderer* renderer) {
211   VideoChannel* video_channel = GetVideoChannel(session);
212   if (video_channel) {
213     video_channel->SetRenderer(ssrc, renderer);
214     LOG(LS_INFO) << "Set renderer of ssrc " << ssrc
215                  << " to " << renderer << ".";
216   } else {
217     LOG(LS_INFO) << "Failed to set renderer of ssrc " << ssrc << ".";
218   }
219 }
220 
OnMessage(rtc::Message * message)221 void Call::OnMessage(rtc::Message* message) {
222   switch (message->message_id) {
223   case MSG_CHECKAUTODESTROY:
224     // If no more sessions for this call, delete it
225     if (media_session_map_.empty())
226       session_client_->DestroyCall(this);
227     break;
228   case MSG_TERMINATECALL:
229     // Signal to the user that a timeout has happened and the call should
230     // be sent to voicemail.
231     if (send_to_voicemail_) {
232       SignalSetupToCallVoicemail();
233     }
234 
235     // Callee didn't answer - terminate call
236     Terminate();
237     break;
238   case MSG_PLAYDTMF:
239     ContinuePlayDTMF();
240   }
241 }
242 
sessions()243 std::vector<Session*> Call::sessions() {
244   std::vector<Session*> sessions;
245   MediaSessionMap::iterator it;
246   for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it)
247     sessions.push_back(it->second.session);
248 
249   return sessions;
250 }
251 
AddSession(Session * session,const SessionDescription * offer)252 bool Call::AddSession(Session* session, const SessionDescription* offer) {
253   bool succeeded = true;
254   MediaSession media_session;
255   media_session.session = session;
256   media_session.voice_channel = NULL;
257   media_session.video_channel = NULL;
258   media_session.data_channel = NULL;
259   media_session.recv_streams = NULL;
260 
261   const ContentInfo* audio_offer = GetFirstAudioContent(offer);
262   const ContentInfo* video_offer = GetFirstVideoContent(offer);
263   const ContentInfo* data_offer = GetFirstDataContent(offer);
264   has_video_ = (video_offer != NULL);
265   has_data_ = (data_offer != NULL);
266 
267   ASSERT(audio_offer != NULL);
268   // Create voice channel and start a media monitor.
269   media_session.voice_channel =
270       session_client_->channel_manager()->CreateVoiceChannel(
271           session, audio_offer->name, has_video_);
272   // voice_channel can be NULL in case of NullVoiceEngine.
273   if (media_session.voice_channel) {
274     media_session.voice_channel->SignalMediaMonitor.connect(
275         this, &Call::OnMediaMonitor);
276     media_session.voice_channel->StartMediaMonitor(kMediaMonitorInterval);
277   } else {
278     succeeded = false;
279   }
280 
281   // If desired, create video channel and start a media monitor.
282   if (has_video_ && succeeded) {
283     media_session.video_channel =
284         session_client_->channel_manager()->CreateVideoChannel(
285             session, video_offer->name, true, media_session.voice_channel);
286     // video_channel can be NULL in case of NullVideoEngine.
287     if (media_session.video_channel) {
288       media_session.video_channel->SignalMediaMonitor.connect(
289           this, &Call::OnMediaMonitor);
290       media_session.video_channel->StartMediaMonitor(kMediaMonitorInterval);
291     } else {
292       succeeded = false;
293     }
294   }
295 
296   // If desired, create data channel.
297   if (has_data_ && succeeded) {
298     const DataContentDescription* data = GetFirstDataContentDescription(offer);
299     if (data == NULL) {
300       succeeded = false;
301     } else {
302       DataChannelType data_channel_type = DCT_RTP;
303       if ((data->protocol() == kMediaProtocolSctp) ||
304           (data->protocol() == kMediaProtocolDtlsSctp)) {
305         data_channel_type = DCT_SCTP;
306       }
307 
308       bool rtcp = false;
309       media_session.data_channel =
310           session_client_->channel_manager()->CreateDataChannel(
311               session, data_offer->name, rtcp, data_channel_type);
312       if (media_session.data_channel) {
313         media_session.data_channel->SignalDataReceived.connect(
314             this, &Call::OnDataReceived);
315       } else {
316         succeeded = false;
317       }
318     }
319   }
320 
321   if (succeeded) {
322     // Add session to list, create channels for this session.
323     media_session.recv_streams = new MediaStreams;
324     media_session_map_[session->id()] = media_session;
325     session->SignalState.connect(this, &Call::OnSessionState);
326     session->SignalError.connect(this, &Call::OnSessionError);
327     session->SignalInfoMessage.connect(
328         this, &Call::OnSessionInfoMessage);
329     session->SignalRemoteDescriptionUpdate.connect(
330         this, &Call::OnRemoteDescriptionUpdate);
331     session->SignalReceivedTerminateReason
332       .connect(this, &Call::OnReceivedTerminateReason);
333 
334     // If this call has the focus, enable this session's channels.
335     if (session_client_->GetFocus() == this) {
336       EnableSessionChannels(session, true);
337     }
338 
339     // Signal client.
340     SignalAddSession(this, session);
341   }
342 
343   return succeeded;
344 }
345 
RemoveSession(Session * session)346 void Call::RemoveSession(Session* session) {
347   MediaSessionMap::iterator it = media_session_map_.find(session->id());
348   if (it == media_session_map_.end())
349     return;
350 
351   // Remove all the screencasts, if they haven't been already.
352   while (!it->second.started_screencasts.empty()) {
353     uint32 ssrc = it->second.started_screencasts.begin()->first;
354     if (!StopScreencastWithoutSendingUpdate(it->second.session, ssrc)) {
355       LOG(LS_ERROR) << "Unable to stop screencast with ssrc " << ssrc;
356       ASSERT(false);
357     }
358   }
359 
360   // Destroy video channel
361   VideoChannel* video_channel = it->second.video_channel;
362   if (video_channel != NULL)
363     session_client_->channel_manager()->DestroyVideoChannel(video_channel);
364 
365   // Destroy voice channel
366   VoiceChannel* voice_channel = it->second.voice_channel;
367   if (voice_channel != NULL)
368     session_client_->channel_manager()->DestroyVoiceChannel(voice_channel);
369 
370   // Destroy data channel
371   DataChannel* data_channel = it->second.data_channel;
372   if (data_channel != NULL)
373     session_client_->channel_manager()->DestroyDataChannel(data_channel);
374 
375   delete it->second.recv_streams;
376   media_session_map_.erase(it);
377 
378   // Destroy speaker monitor
379   StopSpeakerMonitor(session);
380 
381   // Signal client
382   SignalRemoveSession(this, session);
383 
384   // The call auto destroys when the last session is removed
385   rtc::Thread::Current()->Post(this, MSG_CHECKAUTODESTROY);
386 }
387 
GetVoiceChannel(Session * session) const388 VoiceChannel* Call::GetVoiceChannel(Session* session) const {
389   MediaSessionMap::const_iterator it = media_session_map_.find(session->id());
390   return (it != media_session_map_.end()) ? it->second.voice_channel : NULL;
391 }
392 
GetVideoChannel(Session * session) const393 VideoChannel* Call::GetVideoChannel(Session* session) const {
394   MediaSessionMap::const_iterator it = media_session_map_.find(session->id());
395   return (it != media_session_map_.end()) ? it->second.video_channel : NULL;
396 }
397 
GetDataChannel(Session * session) const398 DataChannel* Call::GetDataChannel(Session* session) const {
399   MediaSessionMap::const_iterator it = media_session_map_.find(session->id());
400   return (it != media_session_map_.end()) ? it->second.data_channel : NULL;
401 }
402 
GetMediaStreams(Session * session) const403 MediaStreams* Call::GetMediaStreams(Session* session) const {
404   MediaSessionMap::const_iterator it = media_session_map_.find(session->id());
405   return (it != media_session_map_.end()) ? it->second.recv_streams : NULL;
406 }
407 
EnableChannels(bool enable)408 void Call::EnableChannels(bool enable) {
409   MediaSessionMap::iterator it;
410   for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it) {
411     EnableSessionChannels(it->second.session, enable);
412   }
413 }
414 
EnableSessionChannels(Session * session,bool enable)415 void Call::EnableSessionChannels(Session* session, bool enable) {
416   MediaSessionMap::iterator it = media_session_map_.find(session->id());
417   if (it == media_session_map_.end())
418     return;
419 
420   VoiceChannel* voice_channel = it->second.voice_channel;
421   VideoChannel* video_channel = it->second.video_channel;
422   DataChannel* data_channel = it->second.data_channel;
423   if (voice_channel != NULL)
424     voice_channel->Enable(enable);
425   if (video_channel != NULL)
426     video_channel->Enable(enable);
427   if (data_channel != NULL)
428     data_channel->Enable(enable);
429 }
430 
Mute(bool mute)431 void Call::Mute(bool mute) {
432   muted_ = mute;
433   MediaSessionMap::iterator it;
434   for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it) {
435     if (it->second.voice_channel != NULL)
436       it->second.voice_channel->MuteStream(0, mute);
437   }
438 }
439 
MuteVideo(bool mute)440 void Call::MuteVideo(bool mute) {
441   video_muted_ = mute;
442   MediaSessionMap::iterator it;
443   for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it) {
444     if (it->second.video_channel != NULL)
445       it->second.video_channel->MuteStream(0, mute);
446   }
447 }
448 
SendData(Session * session,const SendDataParams & params,const rtc::Buffer & payload,SendDataResult * result)449 bool Call::SendData(Session* session,
450                     const SendDataParams& params,
451                     const rtc::Buffer& payload,
452                     SendDataResult* result) {
453   DataChannel* data_channel = GetDataChannel(session);
454   if (!data_channel) {
455     LOG(LS_WARNING) << "Could not send data: no data channel.";
456     return false;
457   }
458 
459   return data_channel->SendData(params, payload, result);
460 }
461 
PressDTMF(int event)462 void Call::PressDTMF(int event) {
463   // Queue up this digit
464   if (queued_dtmf_.size() < kMaxDTMFDigits) {
465     LOG(LS_INFO) << "Call::PressDTMF(" << event << ")";
466 
467     queued_dtmf_.push_back(event);
468 
469     if (!playing_dtmf_) {
470       ContinuePlayDTMF();
471     }
472   }
473 }
474 
ScreencastFormatFromFps(int fps)475 cricket::VideoFormat ScreencastFormatFromFps(int fps) {
476   // The capturer pretty much ignore this, but just in case we give it
477   // a resolution big enough to cover any expected desktop.  In any
478   // case, it can't be 0x0, or the CaptureManager will fail to use it.
479   return cricket::VideoFormat(
480       1, 1,
481       cricket::VideoFormat::FpsToInterval(fps), cricket::FOURCC_ANY);
482 }
483 
StartScreencast(Session * session,const std::string & streamid,uint32 ssrc,const ScreencastId & screenid,int fps)484 bool Call::StartScreencast(Session* session,
485                            const std::string& streamid, uint32 ssrc,
486                            const ScreencastId& screenid, int fps) {
487   MediaSessionMap::iterator it = media_session_map_.find(session->id());
488   if (it == media_session_map_.end()) {
489     return false;
490   }
491 
492   VideoChannel *video_channel = GetVideoChannel(session);
493   if (!video_channel) {
494     LOG(LS_WARNING) << "Cannot add screencast"
495                     << " because there is no video channel.";
496     return false;
497   }
498 
499   VideoCapturer* capturer = session_client_->channel_manager()->
500       CreateScreenCapturer(screenid);
501   if (!capturer) {
502     LOG(LS_WARNING) << "Could not create screencast capturer.";
503     return false;
504   }
505 
506   if (!video_channel->AddScreencast(ssrc, capturer)) {
507     delete capturer;
508     LOG(LS_WARNING) << "Could not add screencast capturer.";
509     return false;
510   }
511 
512   VideoFormat format = ScreencastFormatFromFps(fps);
513   if (!session_client_->channel_manager()->StartVideoCapture(
514           capturer, format)) {
515     LOG(LS_WARNING) << "Could not start video capture.";
516     video_channel->RemoveScreencast(ssrc);
517     return false;
518   }
519 
520   if (!video_channel->SetCapturer(ssrc, capturer)) {
521     LOG(LS_WARNING) << "Could not start sending screencast.";
522     session_client_->channel_manager()->StopVideoCapture(
523         capturer, ScreencastFormatFromFps(fps));
524     video_channel->RemoveScreencast(ssrc);
525   }
526 
527   // TODO(pthatcher): Once the CaptureManager has a nicer interface
528   // for removing captures (such as having StartCapture return a
529   // handle), remove this StartedCapture stuff.
530   it->second.started_screencasts.insert(
531       std::make_pair(ssrc, StartedCapture(capturer, format)));
532 
533   // TODO(pthatcher): Verify we aren't re-using an existing id or
534   // ssrc.
535   StreamParams stream;
536   stream.id = streamid;
537   stream.ssrcs.push_back(ssrc);
538   VideoContentDescription* video = CreateVideoStreamUpdate(stream);
539 
540   // TODO(pthatcher): Wait until view request before sending video.
541   video_channel->SetLocalContent(video, CA_UPDATE, NULL);
542   SendVideoStreamUpdate(session, video);
543   return true;
544 }
545 
StopScreencast(Session * session,const std::string & streamid,uint32 ssrc)546 bool Call::StopScreencast(Session* session,
547                           const std::string& streamid, uint32 ssrc) {
548   if (!StopScreencastWithoutSendingUpdate(session, ssrc)) {
549     return false;
550   }
551 
552   VideoChannel *video_channel = GetVideoChannel(session);
553   if (!video_channel) {
554     LOG(LS_WARNING) << "Cannot add screencast"
555                     << " because there is no video channel.";
556     return false;
557   }
558 
559   StreamParams stream;
560   stream.id = streamid;
561   // No ssrcs
562   VideoContentDescription* video = CreateVideoStreamUpdate(stream);
563 
564   video_channel->SetLocalContent(video, CA_UPDATE, NULL);
565   SendVideoStreamUpdate(session, video);
566   return true;
567 }
568 
StopScreencastWithoutSendingUpdate(Session * session,uint32 ssrc)569 bool Call::StopScreencastWithoutSendingUpdate(
570     Session* session, uint32 ssrc) {
571   MediaSessionMap::iterator it = media_session_map_.find(session->id());
572   if (it == media_session_map_.end()) {
573     return false;
574   }
575 
576   VideoChannel *video_channel = GetVideoChannel(session);
577   if (!video_channel) {
578     LOG(LS_WARNING) << "Cannot remove screencast"
579                     << " because there is no video channel.";
580     return false;
581   }
582 
583   StartedScreencastMap::const_iterator screencast_iter =
584       it->second.started_screencasts.find(ssrc);
585   if (screencast_iter == it->second.started_screencasts.end()) {
586     LOG(LS_WARNING) << "Could not stop screencast " << ssrc
587                     << " because there is no capturer.";
588     return false;
589   }
590 
591   VideoCapturer* capturer = screencast_iter->second.capturer;
592   VideoFormat format = screencast_iter->second.format;
593   video_channel->SetCapturer(ssrc, NULL);
594   if (!session_client_->channel_manager()->StopVideoCapture(
595           capturer, format)) {
596     LOG(LS_WARNING) << "Could not stop screencast " << ssrc
597                     << " because could not stop capture.";
598     return false;
599   }
600   video_channel->RemoveScreencast(ssrc);
601   it->second.started_screencasts.erase(ssrc);
602   return true;
603 }
604 
CreateVideoStreamUpdate(const StreamParams & stream)605 VideoContentDescription* Call::CreateVideoStreamUpdate(
606     const StreamParams& stream) {
607   VideoContentDescription* video = new VideoContentDescription();
608   video->set_multistream(true);
609   video->set_partial(true);
610   video->AddStream(stream);
611   return video;
612 }
613 
SendVideoStreamUpdate(Session * session,VideoContentDescription * video)614 void Call::SendVideoStreamUpdate(
615     Session* session, VideoContentDescription* video) {
616   // Takes the ownership of |video|.
617   rtc::scoped_ptr<VideoContentDescription> description(video);
618   const ContentInfo* video_info =
619       GetFirstVideoContent(session->local_description());
620   if (video_info == NULL) {
621     LOG(LS_WARNING) << "Cannot send stream update for video.";
622     return;
623   }
624 
625   std::vector<ContentInfo> contents;
626   contents.push_back(
627       ContentInfo(video_info->name, video_info->type, description.get()));
628 
629   session->SendDescriptionInfoMessage(contents);
630 }
631 
ContinuePlayDTMF()632 void Call::ContinuePlayDTMF() {
633   playing_dtmf_ = false;
634 
635   // Check to see if we have a queued tone
636   if (queued_dtmf_.size() > 0) {
637     playing_dtmf_ = true;
638 
639     int tone = queued_dtmf_.front();
640     queued_dtmf_.pop_front();
641 
642     LOG(LS_INFO) << "Call::ContinuePlayDTMF(" << tone << ")";
643     for (MediaSessionMap::iterator it = media_session_map_.begin();
644          it != media_session_map_.end(); ++it) {
645       if (it->second.voice_channel != NULL) {
646         it->second.voice_channel->PressDTMF(tone, true);
647       }
648     }
649 
650     // Post a message to play the next tone or at least clear the playing_dtmf_
651     // bit.
652     rtc::Thread::Current()->PostDelayed(kDTMFDelay, this, MSG_PLAYDTMF);
653   }
654 }
655 
Join(Call * call,bool enable)656 void Call::Join(Call* call, bool enable) {
657   for (MediaSessionMap::iterator it = call->media_session_map_.begin();
658        it != call->media_session_map_.end(); ++it) {
659     // Shouldn't already exist.
660     ASSERT(media_session_map_.find(it->first) == media_session_map_.end());
661     media_session_map_[it->first] = it->second;
662 
663     it->second.session->SignalState.connect(this, &Call::OnSessionState);
664     it->second.session->SignalError.connect(this, &Call::OnSessionError);
665     it->second.session->SignalReceivedTerminateReason
666       .connect(this, &Call::OnReceivedTerminateReason);
667 
668     EnableSessionChannels(it->second.session, enable);
669   }
670 
671   // Moved all the sessions over, so the other call should no longer have any.
672   call->media_session_map_.clear();
673 }
674 
StartConnectionMonitor(Session * session,int cms)675 void Call::StartConnectionMonitor(Session* session, int cms) {
676   VoiceChannel* voice_channel = GetVoiceChannel(session);
677   if (voice_channel) {
678     voice_channel->SignalConnectionMonitor.connect(this,
679         &Call::OnConnectionMonitor);
680     voice_channel->StartConnectionMonitor(cms);
681   }
682 
683   VideoChannel* video_channel = GetVideoChannel(session);
684   if (video_channel) {
685     video_channel->SignalConnectionMonitor.connect(this,
686         &Call::OnConnectionMonitor);
687     video_channel->StartConnectionMonitor(cms);
688   }
689 }
690 
StopConnectionMonitor(Session * session)691 void Call::StopConnectionMonitor(Session* session) {
692   VoiceChannel* voice_channel = GetVoiceChannel(session);
693   if (voice_channel) {
694     voice_channel->StopConnectionMonitor();
695     voice_channel->SignalConnectionMonitor.disconnect(this);
696   }
697 
698   VideoChannel* video_channel = GetVideoChannel(session);
699   if (video_channel) {
700     video_channel->StopConnectionMonitor();
701     video_channel->SignalConnectionMonitor.disconnect(this);
702   }
703 }
704 
StartAudioMonitor(Session * session,int cms)705 void Call::StartAudioMonitor(Session* session, int cms) {
706   VoiceChannel* voice_channel = GetVoiceChannel(session);
707   if (voice_channel) {
708     voice_channel->SignalAudioMonitor.connect(this, &Call::OnAudioMonitor);
709     voice_channel->StartAudioMonitor(cms);
710   }
711 }
712 
StopAudioMonitor(Session * session)713 void Call::StopAudioMonitor(Session* session) {
714   VoiceChannel* voice_channel = GetVoiceChannel(session);
715   if (voice_channel) {
716     voice_channel->StopAudioMonitor();
717     voice_channel->SignalAudioMonitor.disconnect(this);
718   }
719 }
720 
IsAudioMonitorRunning(Session * session)721 bool Call::IsAudioMonitorRunning(Session* session) {
722   VoiceChannel* voice_channel = GetVoiceChannel(session);
723   if (voice_channel) {
724     return voice_channel->IsAudioMonitorRunning();
725   } else {
726     return false;
727   }
728 }
729 
StartSpeakerMonitor(Session * session)730 void Call::StartSpeakerMonitor(Session* session) {
731   if (speaker_monitor_map_.find(session->id()) == speaker_monitor_map_.end()) {
732     if (!IsAudioMonitorRunning(session)) {
733       StartAudioMonitor(session, kAudioMonitorPollPeriodMillis);
734     }
735     CurrentSpeakerMonitor* speaker_monitor =
736         new cricket::CurrentSpeakerMonitor(
737             audio_source_proxy_.get(), session);
738     speaker_monitor->SignalUpdate.connect(this, &Call::OnSpeakerMonitor);
739     speaker_monitor->Start();
740     speaker_monitor_map_[session->id()] = speaker_monitor;
741   } else {
742     LOG(LS_WARNING) << "Already started speaker monitor for session "
743                     << session->id() << ".";
744   }
745 }
746 
StopSpeakerMonitor(Session * session)747 void Call::StopSpeakerMonitor(Session* session) {
748   if (speaker_monitor_map_.find(session->id()) == speaker_monitor_map_.end()) {
749     LOG(LS_WARNING) << "Speaker monitor for session "
750                     << session->id() << " already stopped.";
751   } else {
752     CurrentSpeakerMonitor* monitor = speaker_monitor_map_[session->id()];
753     monitor->Stop();
754     speaker_monitor_map_.erase(session->id());
755     delete monitor;
756   }
757 }
758 
OnConnectionMonitor(VoiceChannel * channel,const std::vector<ConnectionInfo> & infos)759 void Call::OnConnectionMonitor(VoiceChannel* channel,
760                                const std::vector<ConnectionInfo> &infos) {
761   SignalConnectionMonitor(this, infos);
762 }
763 
OnMediaMonitor(VoiceChannel * channel,const VoiceMediaInfo & info)764 void Call::OnMediaMonitor(VoiceChannel* channel, const VoiceMediaInfo& info) {
765   last_voice_media_info_ = info;
766   SignalMediaMonitor(this, info);
767 }
768 
OnAudioMonitor(VoiceChannel * channel,const AudioInfo & info)769 void Call::OnAudioMonitor(VoiceChannel* channel, const AudioInfo& info) {
770   SignalAudioMonitor(this, info);
771 }
772 
OnSpeakerMonitor(CurrentSpeakerMonitor * monitor,uint32 ssrc)773 void Call::OnSpeakerMonitor(CurrentSpeakerMonitor* monitor, uint32 ssrc) {
774   Session* session = static_cast<Session*>(monitor->session());
775   MediaStreams* recv_streams = GetMediaStreams(session);
776   if (recv_streams) {
777     StreamParams stream;
778     recv_streams->GetAudioStream(StreamSelector(ssrc), &stream);
779     SignalSpeakerMonitor(this, session, stream);
780   }
781 }
782 
OnConnectionMonitor(VideoChannel * channel,const std::vector<ConnectionInfo> & infos)783 void Call::OnConnectionMonitor(VideoChannel* channel,
784                                const std::vector<ConnectionInfo> &infos) {
785   SignalVideoConnectionMonitor(this, infos);
786 }
787 
OnMediaMonitor(VideoChannel * channel,const VideoMediaInfo & info)788 void Call::OnMediaMonitor(VideoChannel* channel, const VideoMediaInfo& info) {
789   SignalVideoMediaMonitor(this, info);
790 }
791 
OnDataReceived(DataChannel * channel,const ReceiveDataParams & params,const rtc::Buffer & payload)792 void Call::OnDataReceived(DataChannel* channel,
793                           const ReceiveDataParams& params,
794                           const rtc::Buffer& payload) {
795   SignalDataReceived(this, params, payload);
796 }
797 
id()798 uint32 Call::id() {
799   return id_;
800 }
801 
OnSessionState(BaseSession * base_session,BaseSession::State state)802 void Call::OnSessionState(BaseSession* base_session, BaseSession::State state) {
803   Session* session = static_cast<Session*>(base_session);
804   switch (state) {
805     case Session::STATE_RECEIVEDACCEPT:
806       UpdateRemoteMediaStreams(session,
807           session->remote_description()->contents(), false);
808       session_client_->session_manager()->signaling_thread()->Clear(this,
809           MSG_TERMINATECALL);
810       break;
811     case Session::STATE_RECEIVEDREJECT:
812     case Session::STATE_RECEIVEDTERMINATE:
813       session_client_->session_manager()->signaling_thread()->Clear(this,
814           MSG_TERMINATECALL);
815       break;
816     default:
817       break;
818   }
819   SignalSessionState(this, session, state);
820 }
821 
OnSessionError(BaseSession * base_session,Session::Error error)822 void Call::OnSessionError(BaseSession* base_session, Session::Error error) {
823   session_client_->session_manager()->signaling_thread()->Clear(this,
824       MSG_TERMINATECALL);
825   SignalSessionError(this, static_cast<Session*>(base_session), error);
826 }
827 
OnSessionInfoMessage(Session * session,const buzz::XmlElement * action_elem)828 void Call::OnSessionInfoMessage(Session* session,
829                                 const buzz::XmlElement* action_elem) {
830   if (!IsJingleViewRequest(action_elem)) {
831     return;
832   }
833 
834   ViewRequest view_request;
835   ParseError error;
836   if (!ParseJingleViewRequest(action_elem, &view_request, &error)) {
837     LOG(LS_WARNING) << "Failed to parse view request: " << error.text;
838     return;
839   }
840 
841   VideoChannel* video_channel = GetVideoChannel(session);
842   if (video_channel == NULL) {
843     LOG(LS_WARNING) << "Ignore view request since we have no video channel.";
844     return;
845   }
846 
847   if (!video_channel->ApplyViewRequest(view_request)) {
848     LOG(LS_WARNING) << "Failed to ApplyViewRequest.";
849   }
850 }
851 
OnRemoteDescriptionUpdate(BaseSession * base_session,const ContentInfos & updated_contents)852 void Call::OnRemoteDescriptionUpdate(BaseSession* base_session,
853                                      const ContentInfos& updated_contents) {
854   Session* session = static_cast<Session*>(base_session);
855 
856   const ContentInfo* audio_content = GetFirstAudioContent(updated_contents);
857   if (audio_content) {
858     const AudioContentDescription* audio_update =
859         static_cast<const AudioContentDescription*>(audio_content->description);
860     if (!audio_update->codecs().empty()) {
861       UpdateVoiceChannelRemoteContent(session, audio_update);
862     }
863   }
864 
865   const ContentInfo* video_content = GetFirstVideoContent(updated_contents);
866   if (video_content) {
867     const VideoContentDescription* video_update =
868         static_cast<const VideoContentDescription*>(video_content->description);
869     if (!video_update->codecs().empty()) {
870       UpdateVideoChannelRemoteContent(session, video_update);
871     }
872   }
873 
874   const ContentInfo* data_content = GetFirstDataContent(updated_contents);
875   if (data_content) {
876     const DataContentDescription* data_update =
877         static_cast<const DataContentDescription*>(data_content->description);
878     if (!data_update->codecs().empty()) {
879       UpdateDataChannelRemoteContent(session, data_update);
880     }
881   }
882 
883   UpdateRemoteMediaStreams(session, updated_contents, true);
884 }
885 
UpdateVoiceChannelRemoteContent(Session * session,const AudioContentDescription * audio)886 bool Call::UpdateVoiceChannelRemoteContent(
887     Session* session, const AudioContentDescription* audio) {
888   VoiceChannel* voice_channel = GetVoiceChannel(session);
889   if (!voice_channel->SetRemoteContent(audio, CA_UPDATE, NULL)) {
890     const std::string error_desc =
891         "Failure in audio SetRemoteContent with CA_UPDATE";
892     LOG(LS_ERROR) << error_desc;
893     session->SetError(BaseSession::ERROR_CONTENT, error_desc);
894     return false;
895   }
896   return true;
897 }
898 
UpdateVideoChannelRemoteContent(Session * session,const VideoContentDescription * video)899 bool Call::UpdateVideoChannelRemoteContent(
900     Session* session, const VideoContentDescription* video) {
901   VideoChannel* video_channel = GetVideoChannel(session);
902   if (!video_channel->SetRemoteContent(video, CA_UPDATE, NULL)) {
903     const std::string error_desc =
904         "Failure in video SetRemoteContent with CA_UPDATE";
905     LOG(LS_ERROR) << error_desc;
906     session->SetError(BaseSession::ERROR_CONTENT, error_desc);
907     return false;
908   }
909   return true;
910 }
911 
UpdateDataChannelRemoteContent(Session * session,const DataContentDescription * data)912 bool Call::UpdateDataChannelRemoteContent(
913     Session* session, const DataContentDescription* data) {
914   DataChannel* data_channel = GetDataChannel(session);
915   if (!data_channel->SetRemoteContent(data, CA_UPDATE, NULL)) {
916     const std::string error_desc =
917         "Failure in data SetRemoteContent with CA_UPDATE";
918     LOG(LS_ERROR) << error_desc;
919     session->SetError(BaseSession::ERROR_CONTENT, error_desc);
920     return false;
921   }
922   return true;
923 }
924 
UpdateRemoteMediaStreams(Session * session,const ContentInfos & updated_contents,bool update_channels)925 void Call::UpdateRemoteMediaStreams(Session* session,
926                                     const ContentInfos& updated_contents,
927                                     bool update_channels) {
928   MediaStreams* recv_streams = GetMediaStreams(session);
929   if (!recv_streams)
930     return;
931 
932   cricket::MediaStreams added_streams;
933   cricket::MediaStreams removed_streams;
934 
935   const ContentInfo* audio_content = GetFirstAudioContent(updated_contents);
936   if (audio_content) {
937     const AudioContentDescription* audio_update =
938         static_cast<const AudioContentDescription*>(audio_content->description);
939     UpdateRecvStreams(audio_update->streams(),
940                       update_channels ? GetVoiceChannel(session) : NULL,
941                       recv_streams->mutable_audio(),
942                       added_streams.mutable_audio(),
943                       removed_streams.mutable_audio());
944   }
945 
946   const ContentInfo* video_content = GetFirstVideoContent(updated_contents);
947   if (video_content) {
948     const VideoContentDescription* video_update =
949         static_cast<const VideoContentDescription*>(video_content->description);
950     UpdateRecvStreams(video_update->streams(),
951                       update_channels ? GetVideoChannel(session) : NULL,
952                       recv_streams->mutable_video(),
953                       added_streams.mutable_video(),
954                       removed_streams.mutable_video());
955   }
956 
957   const ContentInfo* data_content = GetFirstDataContent(updated_contents);
958   if (data_content) {
959     const DataContentDescription* data_update =
960         static_cast<const DataContentDescription*>(data_content->description);
961     UpdateRecvStreams(data_update->streams(),
962                       update_channels ? GetDataChannel(session) : NULL,
963                       recv_streams->mutable_data(),
964                       added_streams.mutable_data(),
965                       removed_streams.mutable_data());
966   }
967 
968   if (!added_streams.empty() || !removed_streams.empty()) {
969     SignalMediaStreamsUpdate(this, session, added_streams, removed_streams);
970   }
971 }
972 
FindStreamChanges(const std::vector<StreamParams> & streams,const std::vector<StreamParams> & updates,std::vector<StreamParams> * added_streams,std::vector<StreamParams> * removed_streams)973 void FindStreamChanges(const std::vector<StreamParams>& streams,
974                        const std::vector<StreamParams>& updates,
975                        std::vector<StreamParams>* added_streams,
976                        std::vector<StreamParams>* removed_streams) {
977   for (std::vector<StreamParams>::const_iterator update = updates.begin();
978        update != updates.end(); ++update) {
979     StreamParams stream;
980     if (GetStreamByIds(streams, update->groupid, update->id, &stream)) {
981       if (!update->has_ssrcs()) {
982         removed_streams->push_back(stream);
983       }
984     } else {
985       // There's a bug on reflector that will send <stream>s even
986       // though there is not ssrc (which means there isn't really a
987       // stream).  To work around it, we simply ignore new <stream>s
988       // that don't have any ssrcs.
989       if (update->has_ssrcs()) {
990         added_streams->push_back(*update);
991       }
992     }
993   }
994 }
995 
UpdateRecvStreams(const std::vector<StreamParams> & update_streams,BaseChannel * channel,std::vector<StreamParams> * recv_streams,std::vector<StreamParams> * added_streams,std::vector<StreamParams> * removed_streams)996 void Call::UpdateRecvStreams(const std::vector<StreamParams>& update_streams,
997                              BaseChannel* channel,
998                              std::vector<StreamParams>* recv_streams,
999                              std::vector<StreamParams>* added_streams,
1000                              std::vector<StreamParams>* removed_streams) {
1001   FindStreamChanges(*recv_streams,
1002                     update_streams, added_streams, removed_streams);
1003   AddRecvStreams(*added_streams,
1004                  channel, recv_streams);
1005   RemoveRecvStreams(*removed_streams,
1006                     channel, recv_streams);
1007 }
1008 
AddRecvStreams(const std::vector<StreamParams> & added_streams,BaseChannel * channel,std::vector<StreamParams> * recv_streams)1009 void Call::AddRecvStreams(const std::vector<StreamParams>& added_streams,
1010                           BaseChannel* channel,
1011                           std::vector<StreamParams>* recv_streams) {
1012   std::vector<StreamParams>::const_iterator stream;
1013   for (stream = added_streams.begin();
1014        stream != added_streams.end();
1015        ++stream) {
1016     AddRecvStream(*stream, channel, recv_streams);
1017   }
1018 }
1019 
AddRecvStream(const StreamParams & stream,BaseChannel * channel,std::vector<StreamParams> * recv_streams)1020 void Call::AddRecvStream(const StreamParams& stream,
1021                          BaseChannel* channel,
1022                          std::vector<StreamParams>* recv_streams) {
1023   if (channel && stream.has_ssrcs()) {
1024     channel->AddRecvStream(stream);
1025   }
1026   recv_streams->push_back(stream);
1027 }
1028 
RemoveRecvStreams(const std::vector<StreamParams> & removed_streams,BaseChannel * channel,std::vector<StreamParams> * recv_streams)1029 void Call::RemoveRecvStreams(const std::vector<StreamParams>& removed_streams,
1030                              BaseChannel* channel,
1031                              std::vector<StreamParams>* recv_streams) {
1032   std::vector<StreamParams>::const_iterator stream;
1033   for (stream = removed_streams.begin();
1034        stream != removed_streams.end();
1035        ++stream) {
1036     RemoveRecvStream(*stream, channel, recv_streams);
1037   }
1038 }
1039 
RemoveRecvStream(const StreamParams & stream,BaseChannel * channel,std::vector<StreamParams> * recv_streams)1040 void Call::RemoveRecvStream(const StreamParams& stream,
1041                             BaseChannel* channel,
1042                             std::vector<StreamParams>* recv_streams) {
1043   if (channel && stream.has_ssrcs()) {
1044     // TODO(pthatcher): Change RemoveRecvStream to take a stream argument.
1045     channel->RemoveRecvStream(stream.first_ssrc());
1046   }
1047   RemoveStreamByIds(recv_streams, stream.groupid, stream.id);
1048 }
1049 
OnReceivedTerminateReason(Session * session,const std::string & reason)1050 void Call::OnReceivedTerminateReason(Session* session,
1051                                      const std::string& reason) {
1052   session_client_->session_manager()->signaling_thread()->Clear(this,
1053     MSG_TERMINATECALL);
1054   SignalReceivedTerminateReason(this, session, reason);
1055 }
1056 
1057 // TODO(mdodd): Get ride of this method since all Hangouts are using a secure
1058 // connection.
secure() const1059 bool Call::secure() const {
1060   if (session_client_->secure() == SEC_DISABLED) {
1061     return false;
1062   }
1063 
1064   bool ret = true;
1065   int i = 0;
1066 
1067   MediaSessionMap::const_iterator it;
1068   for (it = media_session_map_.begin(); it != media_session_map_.end(); ++it) {
1069     LOG_F(LS_VERBOSE) << "session[" << i
1070                       << "], check local and remote descriptions";
1071     i++;
1072 
1073     if (!SessionDescriptionContainsCrypto(
1074             it->second.session->local_description()) ||
1075         !SessionDescriptionContainsCrypto(
1076             it->second.session->remote_description())) {
1077       ret = false;
1078       break;
1079     }
1080   }
1081 
1082   LOG_F(LS_VERBOSE) << "secure=" << ret;
1083   return ret;
1084 }
1085 
SessionDescriptionContainsCrypto(const SessionDescription * sdesc) const1086 bool Call::SessionDescriptionContainsCrypto(
1087     const SessionDescription* sdesc) const {
1088   if (sdesc == NULL) {
1089     LOG_F(LS_VERBOSE) << "sessionDescription is NULL";
1090     return false;
1091   }
1092 
1093   return ContentContainsCrypto(sdesc->GetContentByName(CN_AUDIO)) &&
1094          ContentContainsCrypto(sdesc->GetContentByName(CN_VIDEO));
1095 }
1096 
InternalInitiateSession(const std::string & id,const buzz::Jid & to,const std::string & initiator_name,const CallOptions & options)1097 Session* Call::InternalInitiateSession(const std::string& id,
1098                                        const buzz::Jid& to,
1099                                        const std::string& initiator_name,
1100                                        const CallOptions& options) {
1101   const SessionDescription* offer = session_client_->CreateOffer(options);
1102 
1103   Session* session = session_client_->CreateSession(id, this);
1104   // Only override the initiator_name if it was manually supplied. Otherwise,
1105   // session_client_ will supply the local jid as initiator in CreateOffer.
1106   if (!initiator_name.empty()) {
1107     session->set_initiator_name(initiator_name);
1108   }
1109 
1110   AddSession(session, offer);
1111   session->Initiate(to.Str(), offer);
1112 
1113   // After this timeout, terminate the call because the callee isn't
1114   // answering
1115   session_client_->session_manager()->signaling_thread()->Clear(this,
1116       MSG_TERMINATECALL);
1117   session_client_->session_manager()->signaling_thread()->PostDelayed(
1118     send_to_voicemail_ ? kSendToVoicemailTimeout : kNoVoicemailTimeout,
1119     this, MSG_TERMINATECALL);
1120   return session;
1121 }
1122 
GetAudioSourceProxy()1123 AudioSourceProxy* Call::GetAudioSourceProxy() {
1124   return audio_source_proxy_.get();
1125 }
1126 
1127 }  // namespace cricket
1128