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
40namespace cricket {
41
42const uint32 MSG_CHECKAUTODESTROY = 1;
43const uint32 MSG_TERMINATECALL = 2;
44const uint32 MSG_PLAYDTMF = 3;
45
46namespace {
47const int kDTMFDelay = 300;  // msec
48const size_t kMaxDTMFDigits = 30;
49const int kSendToVoicemailTimeout = 1000*20;
50const int kNoVoicemailTimeout = 1000*180;
51const int kMediaMonitorInterval = 1000*15;
52// In order to be the same as the server-side switching, this must be 100.
53const int kAudioMonitorPollPeriodMillis = 100;
54
55// V is a pointer type.
56template<class K, class V>
57V 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
64bool 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
78AudioSourceProxy::AudioSourceProxy(Call* call)
79    : call_(call) {
80  call_->SignalAudioMonitor.connect(this, &AudioSourceProxy::OnAudioMonitor);
81  call_->SignalMediaStreamsUpdate.connect(
82      this, &AudioSourceProxy::OnMediaStreamsUpdate);
83}
84
85void AudioSourceProxy::OnAudioMonitor(Call* call, const AudioInfo& info) {
86  SignalAudioMonitor(this, info);
87}
88
89void AudioSourceProxy::OnMediaStreamsUpdate(Call* call, Session* session,
90    const MediaStreams& added, const MediaStreams& removed) {
91  SignalMediaStreamsUpdate(this, session, added, removed);
92}
93
94Call::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
106Call::~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
115Session* 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
123Session *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
130void 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
143void 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
153void 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
160void 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
168void 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
179bool 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
209void 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
221void 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
243std::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
252bool 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
346void 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
388VoiceChannel* 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
393VideoChannel* 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
398DataChannel* 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
403MediaStreams* 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
408void 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
415void 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
431void 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
440void 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
449bool 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
462void 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
475cricket::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
484bool 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
546bool 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
569bool 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
605VideoContentDescription* 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
614void 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
632void 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
656void 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
675void 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
691void 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
705void 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
713void 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
721bool 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
730void 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
747void 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
759void Call::OnConnectionMonitor(VoiceChannel* channel,
760                               const std::vector<ConnectionInfo> &infos) {
761  SignalConnectionMonitor(this, infos);
762}
763
764void Call::OnMediaMonitor(VoiceChannel* channel, const VoiceMediaInfo& info) {
765  last_voice_media_info_ = info;
766  SignalMediaMonitor(this, info);
767}
768
769void Call::OnAudioMonitor(VoiceChannel* channel, const AudioInfo& info) {
770  SignalAudioMonitor(this, info);
771}
772
773void 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
783void Call::OnConnectionMonitor(VideoChannel* channel,
784                               const std::vector<ConnectionInfo> &infos) {
785  SignalVideoConnectionMonitor(this, infos);
786}
787
788void Call::OnMediaMonitor(VideoChannel* channel, const VideoMediaInfo& info) {
789  SignalVideoMediaMonitor(this, info);
790}
791
792void Call::OnDataReceived(DataChannel* channel,
793                          const ReceiveDataParams& params,
794                          const rtc::Buffer& payload) {
795  SignalDataReceived(this, params, payload);
796}
797
798uint32 Call::id() {
799  return id_;
800}
801
802void 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
822void 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
828void 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
852void 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
886bool 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
899bool 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
912bool 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
925void 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
973void 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
996void 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
1009void 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
1020void 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
1029void 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
1040void 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
1050void 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.
1059bool 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
1086bool 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
1097Session* 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
1123AudioSourceProxy* Call::GetAudioSourceProxy() {
1124  return audio_source_proxy_.get();
1125}
1126
1127}  // namespace cricket
1128