10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/*
20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle
30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2012, Google Inc.
40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without
60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met:
70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer.
100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer in the documentation
120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     and/or other materials provided with the distribution.
130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  3. The name of the author may not be used to endorse or promote products
140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     derived from this software without specific prior written permission.
150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */
270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/examples/peerconnection/client/conductor.h"
290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <utility>
310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/app/webrtc/videosourceinterface.h"
33cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/examples/peerconnection/client/defaults.h"
34cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/media/devices/devicemanager.h"
352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/common.h"
362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/json.h"
372a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/logging.h"
380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Names used for a IceCandidate JSON object.
400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char kCandidateSdpMidName[] = "sdpMid";
410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char kCandidateSdpMlineIndexName[] = "sdpMLineIndex";
420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char kCandidateSdpName[] = "candidate";
430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Names used for a SessionDescription JSON object.
450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char kSessionDescriptionTypeName[] = "type";
460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char kSessionDescriptionSdpName[] = "sdp";
470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass DummySetSessionDescriptionObserver
490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    : public webrtc::SetSessionDescriptionObserver {
500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public:
510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static DummySetSessionDescriptionObserver* Create() {
520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return
532a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        new rtc::RefCountedObject<DummySetSessionDescriptionObserver>();
540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  virtual void OnSuccess() {
560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(INFO) << __FUNCTION__;
570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  virtual void OnFailure(const std::string& error) {
590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(INFO) << __FUNCTION__ << " " << error;
600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org protected:
630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  DummySetSessionDescriptionObserver() {}
640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ~DummySetSessionDescriptionObserver() {}
650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org};
660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgConductor::Conductor(PeerConnectionClient* client, MainWindow* main_wnd)
680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  : peer_id_(-1),
690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    client_(client),
700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    main_wnd_(main_wnd) {
710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  client_->RegisterObserver(this);
720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  main_wnd->RegisterObserver(this);
730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgConductor::~Conductor() {
760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(peer_connection_.get() == NULL);
770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Conductor::connection_active() const {
800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return peer_connection_.get() != NULL;
810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::Close() {
840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  client_->SignOut();
850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  DeletePeerConnection();
860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Conductor::InitializePeerConnection() {
890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(peer_connection_factory_.get() == NULL);
900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(peer_connection_.get() == NULL);
910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  peer_connection_factory_  = webrtc::CreatePeerConnectionFactory();
930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!peer_connection_factory_.get()) {
950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    main_wnd_->MessageBox("Error",
960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        "Failed to initialize PeerConnectionFactory", true);
970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    DeletePeerConnection();
980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  webrtc::PeerConnectionInterface::IceServers servers;
1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  webrtc::PeerConnectionInterface::IceServer server;
1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  server.uri = GetPeerConnectionString();
1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  servers.push_back(server);
1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  peer_connection_ = peer_connection_factory_->CreatePeerConnection(servers,
1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                                    NULL,
1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                                    NULL,
108ae5ee62dd388d42612f11e06e707683c133ff840mallinath@webrtc.org                                                                    NULL,
1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                                    this);
1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!peer_connection_.get()) {
1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    main_wnd_->MessageBox("Error",
1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        "CreatePeerConnection failed", true);
1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    DeletePeerConnection();
1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  AddStreams();
1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return peer_connection_.get() != NULL;
1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::DeletePeerConnection() {
1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  peer_connection_ = NULL;
1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  active_streams_.clear();
1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  main_wnd_->StopLocalRenderer();
1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  main_wnd_->StopRemoteRenderer();
1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  peer_connection_factory_ = NULL;
1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  peer_id_ = -1;
1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::EnsureStreamingUI() {
1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(peer_connection_.get() != NULL);
1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (main_wnd_->IsWindow()) {
1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (main_wnd_->current_ui() != MainWindow::STREAMING)
1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      main_wnd_->SwitchToStreamingUI();
1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org//
1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// PeerConnectionObserver implementation.
1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org//
1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::OnError() {
1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  LOG(LS_ERROR) << __FUNCTION__;
1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  main_wnd_->QueueUIThreadCallback(PEER_CONNECTION_ERROR, NULL);
1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Called when a remote stream is added
1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::OnAddStream(webrtc::MediaStreamInterface* stream) {
1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  LOG(INFO) << __FUNCTION__ << " " << stream->label();
1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  stream->AddRef();
1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  main_wnd_->QueueUIThreadCallback(NEW_STREAM_ADDED,
1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                   stream);
1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::OnRemoveStream(webrtc::MediaStreamInterface* stream) {
1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  LOG(INFO) << __FUNCTION__ << " " << stream->label();
1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  stream->AddRef();
1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  main_wnd_->QueueUIThreadCallback(STREAM_REMOVED,
1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                   stream);
1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  LOG(INFO) << __FUNCTION__ << " " << candidate->sdp_mline_index();
1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  Json::StyledWriter writer;
1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  Json::Value jmessage;
1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  jmessage[kCandidateSdpMidName] = candidate->sdp_mid();
1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  jmessage[kCandidateSdpMlineIndexName] = candidate->sdp_mline_index();
1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string sdp;
1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!candidate->ToString(&sdp)) {
1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Failed to serialize candidate";
1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  jmessage[kCandidateSdpName] = sdp;
1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SendMessage(writer.write(jmessage));
1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org//
1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// PeerConnectionClientObserver implementation.
1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org//
1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::OnSignedIn() {
1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  LOG(INFO) << __FUNCTION__;
1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  main_wnd_->SwitchToPeerList(client_->peers());
1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::OnDisconnected() {
1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  LOG(INFO) << __FUNCTION__;
1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  DeletePeerConnection();
1900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (main_wnd_->IsWindow())
1920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    main_wnd_->SwitchToConnectUI();
1930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::OnPeerConnected(int id, const std::string& name) {
1960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  LOG(INFO) << __FUNCTION__;
1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Refresh the list if we're showing it.
1980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (main_wnd_->current_ui() == MainWindow::LIST_PEERS)
1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    main_wnd_->SwitchToPeerList(client_->peers());
2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::OnPeerDisconnected(int id) {
2030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  LOG(INFO) << __FUNCTION__;
2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (id == peer_id_) {
2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(INFO) << "Our peer disconnected";
2060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    main_wnd_->QueueUIThreadCallback(PEER_CONNECTION_CLOSED, NULL);
2070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else {
2080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Refresh the list if we're showing it.
2090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (main_wnd_->current_ui() == MainWindow::LIST_PEERS)
2100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      main_wnd_->SwitchToPeerList(client_->peers());
2110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::OnMessageFromPeer(int peer_id, const std::string& message) {
2150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(peer_id_ == peer_id || peer_id_ == -1);
2160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(!message.empty());
2170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!peer_connection_.get()) {
2190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT(peer_id_ == -1);
2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    peer_id_ = peer_id;
2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!InitializePeerConnection()) {
2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(LS_ERROR) << "Failed to initialize our PeerConnection instance";
2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      client_->SignOut();
2250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return;
2260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else if (peer_id != peer_id_) {
2280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT(peer_id_ != -1);
2290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(WARNING) << "Received a message from unknown peer while already in a "
2300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    "conversation with a different peer.";
2310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
2320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  Json::Reader reader;
2350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  Json::Value jmessage;
2360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!reader.parse(message, jmessage)) {
2370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(WARNING) << "Received unknown message. " << message;
2380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
2390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string type;
2410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string json_object;
2420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  GetStringFromJsonObject(jmessage, kSessionDescriptionTypeName, &type);
2440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!type.empty()) {
2450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    std::string sdp;
2460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!GetStringFromJsonObject(jmessage, kSessionDescriptionSdpName, &sdp)) {
2470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(WARNING) << "Can't parse received session description message.";
2480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return;
2490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    webrtc::SessionDescriptionInterface* session_description(
2510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        webrtc::CreateSessionDescription(type, sdp));
2520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!session_description) {
2530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(WARNING) << "Can't parse received session description message.";
2540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return;
2550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(INFO) << " Received session description :" << message;
2570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    peer_connection_->SetRemoteDescription(
2580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        DummySetSessionDescriptionObserver::Create(), session_description);
2590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (session_description->type() ==
2600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        webrtc::SessionDescriptionInterface::kOffer) {
2610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      peer_connection_->CreateAnswer(this, NULL);
2620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
2640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else {
2650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    std::string sdp_mid;
2660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int sdp_mlineindex = 0;
2670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    std::string sdp;
2680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!GetStringFromJsonObject(jmessage, kCandidateSdpMidName, &sdp_mid) ||
2690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        !GetIntFromJsonObject(jmessage, kCandidateSdpMlineIndexName,
2700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              &sdp_mlineindex) ||
2710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        !GetStringFromJsonObject(jmessage, kCandidateSdpName, &sdp)) {
2720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(WARNING) << "Can't parse received message.";
2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return;
2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2752a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<webrtc::IceCandidateInterface> candidate(
2760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        webrtc::CreateIceCandidate(sdp_mid, sdp_mlineindex, sdp));
2770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!candidate.get()) {
2780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(WARNING) << "Can't parse received candidate message.";
2790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return;
2800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!peer_connection_->AddIceCandidate(candidate.get())) {
2820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(WARNING) << "Failed to apply the received candidate";
2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return;
2840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(INFO) << " Received candidate :" << message;
2860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
2870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::OnMessageSent(int err) {
2910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Process the next pending message if any.
2920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  main_wnd_->QueueUIThreadCallback(SEND_MESSAGE_TO_PEER, NULL);
2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::OnServerConnectionFailure() {
2960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    main_wnd_->MessageBox("Error", ("Failed to connect to " + server_).c_str(),
2970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          true);
2980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org//
3010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// MainWndCallback implementation.
3020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org//
3030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::StartLogin(const std::string& server, int port) {
3050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (client_->is_connected())
3060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
3070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  server_ = server;
3080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  client_->Connect(server, port, GetPeerName());
3090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::DisconnectFromServer() {
3120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (client_->is_connected())
3130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    client_->SignOut();
3140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::ConnectToPeer(int peer_id) {
3170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(peer_id_ == -1);
3180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(peer_id != -1);
3190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (peer_connection_.get()) {
3210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    main_wnd_->MessageBox("Error",
3220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        "We only support connecting to one peer at a time", true);
3230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
3240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (InitializePeerConnection()) {
3270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    peer_id_ = peer_id;
3280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    peer_connection_->CreateOffer(this, NULL);
3290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else {
3300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    main_wnd_->MessageBox("Error", "Failed to initialize PeerConnection", true);
3310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgcricket::VideoCapturer* Conductor::OpenVideoCaptureDevice() {
3352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<cricket::DeviceManagerInterface> dev_manager(
3360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      cricket::DeviceManagerFactory::Create());
3370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!dev_manager->Init()) {
3380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Can't create device manager";
3390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return NULL;
3400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::vector<cricket::Device> devs;
3420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!dev_manager->GetVideoCaptureDevices(&devs)) {
3430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Can't enumerate video devices";
3440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return NULL;
3450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::vector<cricket::Device>::iterator dev_it = devs.begin();
3470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  cricket::VideoCapturer* capturer = NULL;
3480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (; dev_it != devs.end(); ++dev_it) {
3490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    capturer = dev_manager->CreateVideoCapturer(*dev_it);
3500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (capturer != NULL)
3510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
3520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return capturer;
3540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::AddStreams() {
3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (active_streams_.find(kStreamLabel) != active_streams_.end())
3580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;  // Already added.
3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3602a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
3610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      peer_connection_factory_->CreateAudioTrack(
3620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          kAudioLabel, peer_connection_factory_->CreateAudioSource(NULL)));
3630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3642a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
3650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      peer_connection_factory_->CreateVideoTrack(
3660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          kVideoLabel,
3670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          peer_connection_factory_->CreateVideoSource(OpenVideoCaptureDevice(),
3680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                      NULL)));
3690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  main_wnd_->StartLocalRenderer(video_track);
3700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3712a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_refptr<webrtc::MediaStreamInterface> stream =
3720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      peer_connection_factory_->CreateLocalMediaStream(kStreamLabel);
3730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  stream->AddTrack(audio_track);
3750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  stream->AddTrack(video_track);
3760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!peer_connection_->AddStream(stream, NULL)) {
3770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Adding stream to PeerConnection failed";
3780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  typedef std::pair<std::string,
3802a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                    rtc::scoped_refptr<webrtc::MediaStreamInterface> >
3810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      MediaStreamPair;
3820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  active_streams_.insert(MediaStreamPair(stream->label(), stream));
3830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  main_wnd_->SwitchToStreamingUI();
3840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::DisconnectFromCurrentPeer() {
3870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  LOG(INFO) << __FUNCTION__;
3880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (peer_connection_.get()) {
3890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    client_->SendHangUp(peer_id_);
3900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    DeletePeerConnection();
3910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (main_wnd_->IsWindow())
3940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    main_wnd_->SwitchToPeerList(client_->peers());
3950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::UIThreadCallback(int msg_id, void* data) {
3980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  switch (msg_id) {
3990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case PEER_CONNECTION_CLOSED:
4000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(INFO) << "PEER_CONNECTION_CLOSED";
4010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      DeletePeerConnection();
4020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT(active_streams_.empty());
4040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (main_wnd_->IsWindow()) {
4060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        if (client_->is_connected()) {
4070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          main_wnd_->SwitchToPeerList(client_->peers());
4080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        } else {
4090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          main_wnd_->SwitchToConnectUI();
4100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        }
4110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      } else {
4120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        DisconnectFromServer();
4130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
4140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
4150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case SEND_MESSAGE_TO_PEER: {
4170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(INFO) << "SEND_MESSAGE_TO_PEER";
4180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      std::string* msg = reinterpret_cast<std::string*>(data);
4190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (msg) {
4200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        // For convenience, we always run the message through the queue.
4210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        // This way we can be sure that messages are sent to the server
4220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        // in the same order they were signaled without much hassle.
4230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        pending_messages_.push_back(msg);
4240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
4250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (!pending_messages_.empty() && !client_->IsSendingMessage()) {
4270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        msg = pending_messages_.front();
4280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        pending_messages_.pop_front();
4290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        if (!client_->SendToPeer(peer_id_, *msg) && peer_id_ != -1) {
4310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          LOG(LS_ERROR) << "SendToPeer failed";
4320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          DisconnectFromServer();
4330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        }
4340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        delete msg;
4350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
4360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (!peer_connection_.get())
4380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        peer_id_ = -1;
4390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
4410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
4420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case PEER_CONNECTION_ERROR:
4440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      main_wnd_->MessageBox("Error", "an unknown error occurred", true);
4450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
4460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case NEW_STREAM_ADDED: {
4480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      webrtc::MediaStreamInterface* stream =
4490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          reinterpret_cast<webrtc::MediaStreamInterface*>(
4500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          data);
4510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      webrtc::VideoTrackVector tracks = stream->GetVideoTracks();
4520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // Only render the first track.
4530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (!tracks.empty()) {
4540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        webrtc::VideoTrackInterface* track = tracks[0];
4550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        main_wnd_->StartRemoteRenderer(track);
4560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
4570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      stream->Release();
4580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
4590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
4600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STREAM_REMOVED: {
4620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // Remote peer stopped sending a stream.
4630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      webrtc::MediaStreamInterface* stream =
4640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          reinterpret_cast<webrtc::MediaStreamInterface*>(
4650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          data);
4660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      stream->Release();
4670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
4680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
4690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    default:
4710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT(false);
4720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
4730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
4740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
4750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::OnSuccess(webrtc::SessionDescriptionInterface* desc) {
4770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  peer_connection_->SetLocalDescription(
4780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      DummySetSessionDescriptionObserver::Create(), desc);
4790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  Json::StyledWriter writer;
4800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  Json::Value jmessage;
4810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  jmessage[kSessionDescriptionTypeName] = desc->type();
4820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string sdp;
4830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  desc->ToString(&sdp);
4840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  jmessage[kSessionDescriptionSdpName] = sdp;
4850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SendMessage(writer.write(jmessage));
4860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
4870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::OnFailure(const std::string& error) {
4890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LERROR) << error;
4900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
4910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Conductor::SendMessage(const std::string& json_object) {
4930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string* msg = new std::string(json_object);
4940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  main_wnd_->QueueUIThreadCallback(SEND_MESSAGE_TO_PEER, msg);
4950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
496