15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/rtc_peer_connection_handler.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/command_line.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/debug/trace_event.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/lazy_instance.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/metrics/histogram.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/stl_util.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/common/content_switches.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/renderer/media/media_stream_track.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/renderer/media/peer_connection_tracker.h"
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/media/remote_media_stream_impl.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/renderer/media/rtc_data_channel_handler.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/renderer/media/rtc_dtmf_sender_handler.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/rtc_media_constraints.h"
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/renderer/media/webrtc/webrtc_media_stream_adapter.h"
28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/renderer/media/webrtc_audio_capturer.h"
29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/renderer/media/webrtc_audio_device_impl.h"
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/renderer/media/webrtc_uma_histograms.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/renderer/render_thread_impl.h"
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebMediaConstraints.h"
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebRTCConfiguration.h"
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebRTCDataChannelInit.h"
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebRTCICECandidate.h"
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebRTCOfferOptions.h"
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebRTCSessionDescription.h"
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebRTCSessionDescriptionRequest.h"
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebRTCVoidRequest.h"
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "third_party/WebKit/public/platform/WebURL.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing webrtc::StatsReport;
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing webrtc::StatsReports;
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Converter functions from libjingle types to WebKit types.
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)blink::WebRTCPeerConnectionHandlerClient::ICEGatheringState
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GetWebKitIceGatheringState(
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    webrtc::PeerConnectionInterface::IceGatheringState state) {
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  using blink::WebRTCPeerConnectionHandlerClient;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (state) {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kIceGatheringNew:
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::ICEGatheringStateNew;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kIceGatheringGathering:
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::ICEGatheringStateGathering;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kIceGatheringComplete:
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::ICEGatheringStateNew;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static blink::WebRTCPeerConnectionHandlerClient::ICEConnectionState
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GetWebKitIceConnectionState(
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    webrtc::PeerConnectionInterface::IceConnectionState ice_state) {
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  using blink::WebRTCPeerConnectionHandlerClient;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (ice_state) {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kIceConnectionNew:
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::ICEConnectionStateStarting;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kIceConnectionChecking:
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::ICEConnectionStateChecking;
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kIceConnectionConnected:
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::ICEConnectionStateConnected;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kIceConnectionFailed:
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::ICEConnectionStateFailed;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::ICEConnectionStateDisconnected;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kIceConnectionClosed:
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::ICEConnectionStateClosed;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::ICEConnectionStateClosed;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static blink::WebRTCPeerConnectionHandlerClient::SignalingState
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GetWebKitSignalingState(webrtc::PeerConnectionInterface::SignalingState state) {
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  using blink::WebRTCPeerConnectionHandlerClient;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (state) {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kStable:
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::SignalingStateStable;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kHaveLocalOffer:
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalOffer;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalPrAnswer;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemoteOffer;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemotePrAnswer;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case webrtc::PeerConnectionInterface::kClosed:
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::SignalingStateClosed;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return WebRTCPeerConnectionHandlerClient::SignalingStateClosed;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static blink::WebRTCSessionDescription
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreateWebKitSessionDescription(
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const webrtc::SessionDescriptionInterface* native_desc) {
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebRTCSessionDescription description;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!native_desc) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Native session description is null.";
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return description;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string sdp;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!native_desc->ToString(&sdp)) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to get SDP string of native session description.";
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return description;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  description.initialize(base::UTF8ToUTF16(native_desc->type()),
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         base::UTF8ToUTF16(sdp));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return description;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converter functions from WebKit types to libjingle types.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static void GetNativeRtcConfiguration(
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebRTCConfiguration& server_configuration,
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    webrtc::PeerConnectionInterface::RTCConfiguration* config) {
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (server_configuration.isNull() || !config)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < server_configuration.numberOfServers(); ++i) {
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    webrtc::PeerConnectionInterface::IceServer server;
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebRTCICEServer& webkit_server =
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        server_configuration.server(i);
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    server.username = base::UTF16ToUTF8(webkit_server.username());
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    server.password = base::UTF16ToUTF8(webkit_server.credential());
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    server.uri = webkit_server.uri().spec();
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    config->servers.push_back(server);
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  switch (server_configuration.iceTransports()) {
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  case blink::WebRTCIceTransportsNone:
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    config->type = webrtc::PeerConnectionInterface::kNone;
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    break;
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  case blink::WebRTCIceTransportsRelay:
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    config->type = webrtc::PeerConnectionInterface::kRelay;
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    break;
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  case blink::WebRTCIceTransportsAll:
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    config->type = webrtc::PeerConnectionInterface::kAll;
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    break;
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  default:
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NOTREACHED();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SessionDescriptionRequestTracker {
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SessionDescriptionRequestTracker(RTCPeerConnectionHandler* handler,
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   PeerConnectionTracker::Action action)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : handler_(handler), action_(action) {}
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void TrackOnSuccess(const webrtc::SessionDescriptionInterface* desc) {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string value;
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (desc) {
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      desc->ToString(&value);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value = "type: " + desc->type() + ", sdp: " + value;
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (handler_->peer_connection_tracker())
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      handler_->peer_connection_tracker()->TrackSessionDescriptionCallback(
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          handler_, action_, "OnSuccess", value);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void TrackOnFailure(const std::string& error) {
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (handler_->peer_connection_tracker())
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      handler_->peer_connection_tracker()->TrackSessionDescriptionCallback(
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          handler_, action_, "OnFailure", error);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RTCPeerConnectionHandler* handler_;
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PeerConnectionTracker::Action action_;
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Class mapping responses from calls to libjingle CreateOffer/Answer and
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// the blink::WebRTCSessionDescriptionRequest.
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CreateSessionDescriptionRequest
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public webrtc::CreateSessionDescriptionObserver {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit CreateSessionDescriptionRequest(
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const blink::WebRTCSessionDescriptionRequest& request,
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RTCPeerConnectionHandler* handler,
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PeerConnectionTracker::Action action)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : webkit_request_(request), tracker_(handler, action) {}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnSuccess(webrtc::SessionDescriptionInterface* desc) OVERRIDE {
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tracker_.TrackOnSuccess(desc);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    webkit_request_.requestSucceeded(CreateWebKitSessionDescription(desc));
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    delete desc;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnFailure(const std::string& error) OVERRIDE {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tracker_.TrackOnFailure(error);
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    webkit_request_.requestFailed(base::UTF8ToUTF16(error));
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~CreateSessionDescriptionRequest() {}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebRTCSessionDescriptionRequest webkit_request_;
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SessionDescriptionRequestTracker tracker_;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Class mapping responses from calls to libjingle
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// SetLocalDescription/SetRemoteDescription and a blink::WebRTCVoidRequest.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SetSessionDescriptionRequest
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public webrtc::SetSessionDescriptionObserver {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit SetSessionDescriptionRequest(
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const blink::WebRTCVoidRequest& request,
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RTCPeerConnectionHandler* handler,
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PeerConnectionTracker::Action action)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : webkit_request_(request), tracker_(handler, action) {}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnSuccess() OVERRIDE {
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tracker_.TrackOnSuccess(NULL);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    webkit_request_.requestSucceeded();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnFailure(const std::string& error) OVERRIDE {
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tracker_.TrackOnFailure(error);
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    webkit_request_.requestFailed(base::UTF8ToUTF16(error));
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SetSessionDescriptionRequest() {}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebRTCVoidRequest webkit_request_;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SessionDescriptionRequestTracker tracker_;
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Class mapping responses from calls to libjingle
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// GetStats into a blink::WebRTCStatsCallback.
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class StatsResponse : public webrtc::StatsObserver {
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit StatsResponse(const scoped_refptr<LocalRTCStatsRequest>& request)
25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      : request_(request.get()), response_(request_->createResponse().get()) {
25746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // Measure the overall time it takes to satisfy a getStats request.
25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    TRACE_EVENT_ASYNC_BEGIN0("webrtc", "getStats_Native", this);
25946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void OnComplete(const StatsReports& reports) OVERRIDE {
262effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    TRACE_EVENT0("webrtc", "StatsResponse::OnComplete")
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (StatsReports::const_iterator it = reports.begin();
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         it != reports.end(); ++it) {
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if ((*it)->values.size() > 0) {
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        AddReport(*(*it));
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // Record the getSync operation as done before calling into Blink so that
27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // we don't skew the perf measurements of the native code with whatever the
27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // callback might be doing.
27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    TRACE_EVENT_ASYNC_END0("webrtc", "getStats_Native", this);
27446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    request_->requestSucceeded(response_);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void AddReport(const StatsReport& report) {
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int idx = response_->addReport(blink::WebString::fromUTF8(report.id),
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   blink::WebString::fromUTF8(report.type),
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   report.timestamp);
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (StatsReport::Values::const_iterator value_it = report.values.begin();
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         value_it != report.values.end(); ++value_it) {
2856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      AddStatistic(idx, value_it->display_name(), value_it->value);
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void AddStatistic(int idx, const char* name, const std::string& value) {
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response_->addStatistic(idx,
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            blink::WebString::fromUTF8(name),
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            blink::WebString::fromUTF8(value));
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::scoped_refptr<LocalRTCStatsRequest> request_;
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::scoped_refptr<LocalRTCStatsResponse> response_;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Implementation of LocalRTCStatsRequest.
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)LocalRTCStatsRequest::LocalRTCStatsRequest(blink::WebRTCStatsRequest impl)
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : impl_(impl),
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      response_(NULL) {
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)LocalRTCStatsRequest::LocalRTCStatsRequest() {}
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)LocalRTCStatsRequest::~LocalRTCStatsRequest() {}
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool LocalRTCStatsRequest::hasSelector() const {
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return impl_.hasSelector();
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)blink::WebMediaStreamTrack LocalRTCStatsRequest::component() const {
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return impl_.component();
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<LocalRTCStatsResponse> LocalRTCStatsRequest::createResponse() {
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!response_);
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  response_ = new rtc::RefCountedObject<LocalRTCStatsResponse>(
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      impl_.createResponse());
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return response_.get();
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LocalRTCStatsRequest::requestSucceeded(
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const LocalRTCStatsResponse* response) {
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  impl_.requestSucceeded(response->webKitStatsResponse());
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Implementation of LocalRTCStatsResponse.
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)blink::WebRTCStatsResponse LocalRTCStatsResponse::webKitStatsResponse() const {
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return impl_;
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)size_t LocalRTCStatsResponse::addReport(blink::WebString type,
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        blink::WebString id,
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        double timestamp) {
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return impl_.addReport(type, id, timestamp);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LocalRTCStatsResponse::addStatistic(size_t report,
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                         blink::WebString name,
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                         blink::WebString value) {
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  impl_.addStatistic(report, name, value);
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class PeerConnectionUMAObserver : public webrtc::UMAObserver {
348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PeerConnectionUMAObserver() {}
350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~PeerConnectionUMAObserver() {}
351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void IncrementCounter(
353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      webrtc::PeerConnectionUMAMetricsCounter counter) OVERRIDE {
354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              counter,
356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              webrtc::kBoundary);
357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void AddHistogramSample(
360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      webrtc::PeerConnectionUMAMetricsName type, int value) OVERRIDE {
361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    switch (type) {
362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case webrtc::kTimeToConnect:
363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        UMA_HISTOGRAM_MEDIUM_TIMES(
364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "WebRTC.PeerConnection.TimeToConnect",
365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            base::TimeDelta::FromMilliseconds(value));
366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case webrtc::kNetworkInterfaces_IPv4:
368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        UMA_HISTOGRAM_COUNTS_100("WebRTC.PeerConnection.IPv4Interfaces",
369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                 value);
370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case webrtc::kNetworkInterfaces_IPv6:
372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        UMA_HISTOGRAM_COUNTS_100("WebRTC.PeerConnection.IPv6Interfaces",
373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                 value);
374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      default:
376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        NOTREACHED();
377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)base::LazyInstance<std::set<RTCPeerConnectionHandler*> >::Leaky
382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    g_peer_connection_handlers = LAZY_INSTANCE_INITIALIZER;
383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace
385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RTCPeerConnectionHandler::RTCPeerConnectionHandler(
387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebRTCPeerConnectionHandlerClient* client,
388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PeerConnectionDependencyFactory* dependency_factory)
3890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    : client_(client),
3900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      dependency_factory_(dependency_factory),
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      frame_(NULL),
392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      peer_connection_tracker_(NULL),
3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      num_data_channels_created_(0),
3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      num_local_candidates_ipv4_(0),
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      num_local_candidates_ipv6_(0) {
396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  g_peer_connection_handlers.Get().insert(this);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  g_peer_connection_handlers.Get().erase(this);
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->UnregisterPeerConnection(this);
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  STLDeleteValues(&remote_streams_);
404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_10000(
406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "WebRTC.NumDataChannelsPerPeerConnection", num_data_channels_created_);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static
410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RTCPeerConnectionHandler::DestructAllHandlers() {
411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::set<RTCPeerConnectionHandler*> handlers(
412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      g_peer_connection_handlers.Get().begin(),
413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      g_peer_connection_handlers.Get().end());
414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (std::set<RTCPeerConnectionHandler*>::iterator handler = handlers.begin();
415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       handler != handlers.end();
416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       ++handler) {
417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    (*handler)->client_->releasePeerConnectionHandler();
418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void RTCPeerConnectionHandler::ConvertOfferOptionsToConstraints(
4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const blink::WebRTCOfferOptions& options,
4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RTCMediaConstraints* output) {
4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  output->AddMandatory(
4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      webrtc::MediaConstraintsInterface::kOfferToReceiveAudio,
4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      options.offerToReceiveAudio() > 0 ? "true" : "false",
4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      true);
4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  output->AddMandatory(
4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      webrtc::MediaConstraintsInterface::kOfferToReceiveVideo,
4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      options.offerToReceiveVideo() > 0 ? "true" : "false",
4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      true);
4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!options.voiceActivityDetection()) {
4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    output->AddMandatory(
4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        webrtc::MediaConstraintsInterface::kVoiceActivityDetection,
4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        "false",
4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        true);
4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (options.iceRestart()) {
4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    output->AddMandatory(
4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        webrtc::MediaConstraintsInterface::kIceRestart, "true", true);
4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RTCPeerConnectionHandler::associateWithFrame(blink::WebFrame* frame) {
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(frame);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frame_ = frame;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RTCPeerConnectionHandler::initialize(
453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebRTCConfiguration& server_configuration,
454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebMediaConstraints& options) {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(frame_);
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  peer_connection_tracker_ =
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RenderThreadImpl::current()->peer_connection_tracker();
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  webrtc::PeerConnectionInterface::RTCConfiguration config;
4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GetNativeRtcConfiguration(server_configuration, &config);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RTCMediaConstraints constraints(options);
46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  native_peer_connection_ =
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dependency_factory_->CreatePeerConnection(
4675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          config, &constraints, frame_, this);
4685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!native_peer_connection_.get()) {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to initialize native PeerConnection.";
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->RegisterPeerConnection(
4755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        this, config, constraints, frame_);
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  uma_observer_ = new rtc::RefCountedObject<PeerConnectionUMAObserver>();
478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  native_peer_connection_->RegisterUMAObserver(uma_observer_.get());
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RTCPeerConnectionHandler::InitializeForTest(
483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebRTCConfiguration& server_configuration,
484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebMediaConstraints& options,
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PeerConnectionTracker* peer_connection_tracker) {
4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  webrtc::PeerConnectionInterface::RTCConfiguration config;
4875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GetNativeRtcConfiguration(server_configuration, &config);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RTCMediaConstraints constraints(options);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  native_peer_connection_ =
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dependency_factory_->CreatePeerConnection(
4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          config, &constraints, NULL, this);
493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!native_peer_connection_.get()) {
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to initialize native PeerConnection.";
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  peer_connection_tracker_ = peer_connection_tracker;
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RTCPeerConnectionHandler::createOffer(
502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebRTCSessionDescriptionRequest& request,
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebMediaConstraints& options) {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<CreateSessionDescriptionRequest> description_request(
5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new rtc::RefCountedObject<CreateSessionDescriptionRequest>(
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          request, this, PeerConnectionTracker::ACTION_CREATE_OFFER));
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RTCMediaConstraints constraints(options);
508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  native_peer_connection_->CreateOffer(description_request.get(), &constraints);
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackCreateOffer(this, constraints);
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void RTCPeerConnectionHandler::createOffer(
5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const blink::WebRTCSessionDescriptionRequest& request,
5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const blink::WebRTCOfferOptions& options) {
5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<CreateSessionDescriptionRequest> description_request(
5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new rtc::RefCountedObject<CreateSessionDescriptionRequest>(
5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          request, this, PeerConnectionTracker::ACTION_CREATE_OFFER));
5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RTCMediaConstraints constraints;
5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ConvertOfferOptionsToConstraints(options, &constraints);
5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  native_peer_connection_->CreateOffer(description_request.get(), &constraints);
5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (peer_connection_tracker_)
5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    peer_connection_tracker_->TrackCreateOffer(this, constraints);
5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RTCPeerConnectionHandler::createAnswer(
530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebRTCSessionDescriptionRequest& request,
531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebMediaConstraints& options) {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<CreateSessionDescriptionRequest> description_request(
5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new rtc::RefCountedObject<CreateSessionDescriptionRequest>(
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          request, this, PeerConnectionTracker::ACTION_CREATE_ANSWER));
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RTCMediaConstraints constraints(options);
536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  native_peer_connection_->CreateAnswer(description_request.get(),
537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        &constraints);
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackCreateAnswer(this, constraints);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RTCPeerConnectionHandler::setLocalDescription(
544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebRTCVoidRequest& request,
545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebRTCSessionDescription& description) {
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webrtc::SdpParseError error;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  webrtc::SessionDescriptionInterface* native_desc =
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateNativeSessionDescription(description, &error);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!native_desc) {
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string reason_str = "Failed to parse SessionDescription. ";
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    reason_str.append(error.line);
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    reason_str.append(" ");
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    reason_str.append(error.description);
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << reason_str;
555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    request.requestFailed(blink::WebString::fromUTF8(reason_str));
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackSetSessionDescription(
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        this, description, PeerConnectionTracker::SOURCE_LOCAL);
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SetSessionDescriptionRequest> set_request(
5635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new rtc::RefCountedObject<SetSessionDescriptionRequest>(
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          request, this, PeerConnectionTracker::ACTION_SET_LOCAL_DESCRIPTION));
565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  native_peer_connection_->SetLocalDescription(set_request.get(), native_desc);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RTCPeerConnectionHandler::setRemoteDescription(
569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebRTCVoidRequest& request,
570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebRTCSessionDescription& description) {
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webrtc::SdpParseError error;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  webrtc::SessionDescriptionInterface* native_desc =
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateNativeSessionDescription(description, &error);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!native_desc) {
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string reason_str = "Failed to parse SessionDescription. ";
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    reason_str.append(error.line);
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    reason_str.append(" ");
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    reason_str.append(error.description);
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << reason_str;
580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    request.requestFailed(blink::WebString::fromUTF8(reason_str));
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackSetSessionDescription(
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        this, description, PeerConnectionTracker::SOURCE_REMOTE);
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SetSessionDescriptionRequest> set_request(
5885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new rtc::RefCountedObject<SetSessionDescriptionRequest>(
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          request, this, PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION));
590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  native_peer_connection_->SetRemoteDescription(set_request.get(), native_desc);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)blink::WebRTCSessionDescription
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RTCPeerConnectionHandler::localDescription() {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const webrtc::SessionDescriptionInterface* native_desc =
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      native_peer_connection_->local_description();
597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebRTCSessionDescription description =
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateWebKitSessionDescription(native_desc);
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return description;
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)blink::WebRTCSessionDescription
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RTCPeerConnectionHandler::remoteDescription() {
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const webrtc::SessionDescriptionInterface* native_desc =
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      native_peer_connection_->remote_description();
606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebRTCSessionDescription description =
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateWebKitSessionDescription(native_desc);
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return description;
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RTCPeerConnectionHandler::updateICE(
612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebRTCConfiguration& server_configuration,
613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebMediaConstraints& options) {
6145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  webrtc::PeerConnectionInterface::RTCConfiguration config;
6155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GetNativeRtcConfiguration(server_configuration, &config);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RTCMediaConstraints constraints(options);
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
6195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    peer_connection_tracker_->TrackUpdateIce(this, config, constraints);
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return native_peer_connection_->UpdateIce(config.servers,
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            &constraints);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RTCPeerConnectionHandler::addICECandidate(
626a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const blink::WebRTCVoidRequest& request,
627a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const blink::WebRTCICECandidate& candidate) {
628a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Libjingle currently does not accept callbacks for addICECandidate.
629a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // For that reason we are going to call callbacks from here.
630a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool result = addICECandidate(candidate);
631a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
632a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FROM_HERE,
633a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&RTCPeerConnectionHandler::OnaddICECandidateResult,
634a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 base::Unretained(this), request, result));
635a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // On failure callback will be triggered.
636a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return true;
637a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
638a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
639a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool RTCPeerConnectionHandler::addICECandidate(
640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebRTCICECandidate& candidate) {
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<webrtc::IceCandidateInterface> native_candidate(
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dependency_factory_->CreateIceCandidate(
6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::UTF16ToUTF8(candidate.sdpMid()),
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          candidate.sdpMLineIndex(),
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::UTF16ToUTF8(candidate.candidate())));
6461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool return_value = false;
6471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (native_candidate) {
6491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return_value =
6501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        native_peer_connection_->AddIceCandidate(native_candidate.get());
6511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG_IF(ERROR, !return_value) << "Error processing ICE candidate.";
6521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Could not create native ICE candidate.";
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (peer_connection_tracker_) {
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackAddIceCandidate(
6581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this, candidate, PeerConnectionTracker::SOURCE_REMOTE, return_value);
6591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return return_value;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
663a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void RTCPeerConnectionHandler::OnaddICECandidateResult(
664a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const blink::WebRTCVoidRequest& webkit_request, bool result) {
665a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!result) {
666a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // We don't have the actual error code from the libjingle, so for now
667a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // using a generic error string.
668a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return webkit_request.requestFailed(
6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::UTF8ToUTF16("Error processing ICE candidate"));
670a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
672a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return webkit_request.requestSucceeded();
673a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
674a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RTCPeerConnectionHandler::addStream(
676f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebMediaStream& stream,
677f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebMediaConstraints& options) {
6780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (ScopedVector<WebRtcMediaStreamAdapter>::iterator adapter_it =
6800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      local_streams_.begin(); adapter_it != local_streams_.end();
6810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ++adapter_it) {
6820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if ((*adapter_it)->IsEqual(stream)) {
6830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      DVLOG(1) << "RTCPeerConnectionHandler::addStream called with the same "
6840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch               << "stream twice. id=" << stream.id().utf8();
6850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return false;
6860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
6870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackAddStream(
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        this, stream, PeerConnectionTracker::SOURCE_LOCAL);
692d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
693effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter();
694effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
6950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  WebRtcMediaStreamAdapter* adapter =
6960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new WebRtcMediaStreamAdapter(stream, dependency_factory_);
6970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  local_streams_.push_back(adapter);
6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  webrtc::MediaStreamInterface* webrtc_stream = adapter->webrtc_media_stream();
7000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  track_metrics_.AddStream(MediaStreamTrackMetrics::SENT_STREAM,
7010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                           webrtc_stream);
702d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
7030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RTCMediaConstraints constraints(options);
7040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return native_peer_connection_->AddStream(webrtc_stream, &constraints);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RTCPeerConnectionHandler::removeStream(
708f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebMediaStream& stream) {
7090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Find the webrtc stream.
7100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream;
7110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (ScopedVector<WebRtcMediaStreamAdapter>::iterator adapter_it =
7120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch           local_streams_.begin(); adapter_it != local_streams_.end();
7130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       ++adapter_it) {
7140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if ((*adapter_it)->IsEqual(stream)) {
7150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      webrtc_stream = (*adapter_it)->webrtc_media_stream();
7160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      local_streams_.erase(adapter_it);
7170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      break;
7180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
7190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
7201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(webrtc_stream.get());
7211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  native_peer_connection_->RemoveStream(webrtc_stream.get());
7220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackRemoveStream(
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        this, stream, PeerConnectionTracker::SOURCE_LOCAL);
726effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter();
727effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  track_metrics_.RemoveStream(MediaStreamTrackMetrics::SENT_STREAM,
7281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              webrtc_stream.get());
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RTCPeerConnectionHandler::getStats(
732f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebRTCStatsRequest& request) {
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<LocalRTCStatsRequest> inner_request(
7345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new rtc::RefCountedObject<LocalRTCStatsRequest>(request));
735868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  getStats(inner_request.get());
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RTCPeerConnectionHandler::getStats(LocalRTCStatsRequest* request) {
7395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::scoped_refptr<webrtc::StatsObserver> observer(
7405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new rtc::RefCountedObject<StatsResponse>(request));
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webrtc::MediaStreamTrackInterface* track = NULL;
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (request->hasSelector()) {
7430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    blink::WebMediaStreamSource::Type type =
7440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        request->component().source().type();
7450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    std::string track_id = request->component().id().utf8();
7460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (type == blink::WebMediaStreamSource::TypeAudio) {
7470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      track =
7480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          native_peer_connection_->local_streams()->FindAudioTrack(track_id);
7490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (!track) {
7500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        track =
7510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            native_peer_connection_->remote_streams()->FindAudioTrack(track_id);
7520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      }
7530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    } else {
7540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      DCHECK_EQ(blink::WebMediaStreamSource::TypeVideo, type);
7550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      track =
7560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          native_peer_connection_->local_streams()->FindVideoTrack(track_id);
7570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (!track) {
7580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        track =
7590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            native_peer_connection_->remote_streams()->FindVideoTrack(track_id);
760a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
761a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!track) {
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DVLOG(1) << "GetStats: Track not found.";
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // TODO(hta): Consider how to get an error back.
7651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      observer->OnComplete(StatsReports());
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetStats(observer,
7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)           track,
7715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)           webrtc::PeerConnectionInterface::kStatsOutputLevelStandard);
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RTCPeerConnectionHandler::GetStats(
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    webrtc::StatsObserver* observer,
7765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    webrtc::MediaStreamTrackInterface* track,
7775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    webrtc::PeerConnectionInterface::StatsOutputLevel level) {
778effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::GetStats");
7795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!native_peer_connection_->GetStats(observer, track, level)) {
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DVLOG(1) << "GetStats failed.";
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(hta): Consider how to get an error back.
7821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    observer->OnComplete(StatsReports());
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
78703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void RTCPeerConnectionHandler::CloseClientPeerConnection() {
78803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  client_->closePeerConnection();
78903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
79003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
791f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)blink::WebRTCDataChannelHandler* RTCPeerConnectionHandler::createDataChannel(
792f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebString& label, const blink::WebRTCDataChannelInit& init) {
7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DVLOG(1) << "createDataChannel label " << base::UTF16ToUTF8(label);
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webrtc::DataChannelInit config;
7967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(jiayl): remove the deprecated reliable field once Libjingle is updated
7977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // to handle that.
7987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  config.reliable = false;
7997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  config.id = init.id;
8007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  config.ordered = init.ordered;
8017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  config.negotiated = init.negotiated;
8027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  config.maxRetransmits = init.maxRetransmits;
8037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  config.maxRetransmitTime = init.maxRetransmitTime;
8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  config.protocol = base::UTF16ToUTF8(init.protocol);
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::scoped_refptr<webrtc::DataChannelInterface> webrtc_channel(
8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      native_peer_connection_->CreateDataChannel(base::UTF16ToUTF8(label),
8085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                 &config));
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!webrtc_channel) {
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(ERROR) << "Could not create native data channel.";
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackCreateDataChannel(
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        this, webrtc_channel.get(), PeerConnectionTracker::SOURCE_LOCAL);
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
817a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ++num_data_channels_created_;
818a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new RtcDataChannelHandler(webrtc_channel);
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)blink::WebRTCDTMFSenderHandler* RTCPeerConnectionHandler::createDTMFSender(
823f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebMediaStreamTrack& track) {
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "createDTMFSender.";
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
826a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MediaStreamTrack* native_track = MediaStreamTrack::GetTrack(track);
827a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!native_track ||
828a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      track.source().type() != blink::WebMediaStreamSource::TypeAudio) {
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(ERROR) << "Could not create DTMF sender from a non-audio track.";
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
833a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  webrtc::AudioTrackInterface* audio_track = native_track->GetAudioAdapter();
8345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::scoped_refptr<webrtc::DtmfSenderInterface> sender(
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      native_peer_connection_->CreateDtmfSender(audio_track));
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!sender) {
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(ERROR) << "Could not create native DTMF sender.";
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackCreateDTMFSender(this, track);
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new RtcDtmfSenderHandler(sender);
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RTCPeerConnectionHandler::stop() {
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "RTCPeerConnectionHandler::stop";
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackStop(this);
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_peer_connection_->Close();
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RTCPeerConnectionHandler::OnError() {
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(perkj): Implement.
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTIMPLEMENTED();
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RTCPeerConnectionHandler::OnSignalingChange(
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    webrtc::PeerConnectionInterface::SignalingState new_state) {
861f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebRTCPeerConnectionHandlerClient::SignalingState state =
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetWebKitSignalingState(new_state);
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackSignalingStateChange(this, state);
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client_->didChangeSignalingState(state);
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Called any time the IceConnectionState changes
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RTCPeerConnectionHandler::OnIceConnectionChange(
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    webrtc::PeerConnectionInterface::IceConnectionState new_state) {
8715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (new_state == webrtc::PeerConnectionInterface::kIceConnectionChecking) {
8725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ice_connection_checking_start_ = base::TimeTicks::Now();
8735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else if (new_state ==
8745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      webrtc::PeerConnectionInterface::kIceConnectionConnected) {
8755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // If the state becomes connected, send the time needed for PC to become
8765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // connected from checking to UMA. UMA data will help to know how much
8775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // time needed for PC to connect with remote peer.
8785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UMA_HISTOGRAM_MEDIUM_TIMES(
8795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        "WebRTC.PeerConnection.TimeToConnect",
8805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::TimeTicks::Now() - ice_connection_checking_start_);
8815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
8825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
883effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  track_metrics_.IceConnectionChange(new_state);
884f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebRTCPeerConnectionHandlerClient::ICEConnectionState state =
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetWebKitIceConnectionState(new_state);
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackIceConnectionStateChange(this, state);
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client_->didChangeICEConnectionState(state);
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Called any time the IceGatheringState changes
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RTCPeerConnectionHandler::OnIceGatheringChange(
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    webrtc::PeerConnectionInterface::IceGatheringState new_state) {
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (new_state == webrtc::PeerConnectionInterface::kIceGatheringComplete) {
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If ICE gathering is completed, generate a NULL ICE candidate,
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // to signal end of candidates.
897f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebRTCICECandidate null_candidate;
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    client_->didGenerateICECandidate(null_candidate);
8991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    UMA_HISTOGRAM_COUNTS_100("WebRTC.PeerConnection.IPv4LocalCandidates",
9011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             num_local_candidates_ipv4_);
9021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    UMA_HISTOGRAM_COUNTS_100("WebRTC.PeerConnection.IPv6LocalCandidates",
9041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             num_local_candidates_ipv6_);
9051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else if (new_state ==
9061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci             webrtc::PeerConnectionInterface::kIceGatheringGathering) {
9071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // ICE restarts will change gathering state back to "gathering",
9081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // reset the counter.
9091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    num_local_candidates_ipv6_ = 0;
9101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    num_local_candidates_ipv4_ = 0;
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
913f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebRTCPeerConnectionHandlerClient::ICEGatheringState state =
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetWebKitIceGatheringState(new_state);
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackIceGatheringStateChange(this, state);
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client_->didChangeICEGatheringState(state);
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RTCPeerConnectionHandler::OnAddStream(
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    webrtc::MediaStreamInterface* stream_interface) {
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(stream_interface);
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(remote_streams_.find(stream_interface) == remote_streams_.end());
924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RemoteMediaStreamImpl* remote_stream =
926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new RemoteMediaStreamImpl(stream_interface);
927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  remote_streams_.insert(
928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::pair<webrtc::MediaStreamInterface*, RemoteMediaStreamImpl*> (
929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          stream_interface, remote_stream));
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackAddStream(
933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        this, remote_stream->webkit_stream(),
934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        PeerConnectionTracker::SOURCE_REMOTE);
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
936effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter();
937effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
938effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  track_metrics_.AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM,
939effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                           stream_interface);
940effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  client_->didAddRemoteStream(remote_stream->webkit_stream());
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RTCPeerConnectionHandler::OnRemoveStream(
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    webrtc::MediaStreamInterface* stream_interface) {
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(stream_interface);
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RemoteStreamMap::iterator it = remote_streams_.find(stream_interface);
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == remote_streams_.end()) {
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Stream not found";
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
953effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  track_metrics_.RemoveStream(MediaStreamTrackMetrics::RECEIVED_STREAM,
954effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                              stream_interface);
955effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter();
956effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<RemoteMediaStreamImpl> remote_stream(it->second);
958f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const blink::WebMediaStream& webkit_stream = remote_stream->webkit_stream();
959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!webkit_stream.isNull());
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  remote_streams_.erase(it);
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackRemoveStream(
964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        this, webkit_stream, PeerConnectionTracker::SOURCE_REMOTE);
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  client_->didRemoveRemoteStream(webkit_stream);
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RTCPeerConnectionHandler::OnIceCandidate(
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const webrtc::IceCandidateInterface* candidate) {
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(candidate);
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string sdp;
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!candidate->ToString(&sdp)) {
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "OnIceCandidate: Could not get SDP string.";
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
977f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebRTCICECandidate web_candidate;
9785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  web_candidate.initialize(base::UTF8ToUTF16(sdp),
9795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           base::UTF8ToUTF16(candidate->sdp_mid()),
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           candidate->sdp_mline_index());
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackAddIceCandidate(
9831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this, web_candidate, PeerConnectionTracker::SOURCE_LOCAL, true);
9841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Only the first m line's first component is tracked to avoid
9861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // miscounting when doing BUNDLE or rtcp mux.
9871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (candidate->sdp_mline_index() == 0 &&
9881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      candidate->candidate().component() == 1) {
9891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (candidate->candidate().address().family() == AF_INET) {
9901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      num_local_candidates_ipv4_++;
9911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (candidate->candidate().address().family() == AF_INET6) {
9921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      num_local_candidates_ipv6_++;
9931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
9941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      NOTREACHED();
9951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
9961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_->didGenerateICECandidate(web_candidate);
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RTCPeerConnectionHandler::OnDataChannel(
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    webrtc::DataChannelInterface* data_channel) {
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackCreateDataChannel(
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        this, data_channel, PeerConnectionTracker::SOURCE_REMOTE);
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "RTCPeerConnectionHandler::OnDataChannel "
10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << data_channel->label();
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client_->didAddRemoteDataChannel(new RtcDataChannelHandler(data_channel));
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RTCPeerConnectionHandler::OnRenegotiationNeeded() {
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (peer_connection_tracker_)
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    peer_connection_tracker_->TrackOnRenegotiationNeeded(this);
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_->negotiationNeeded();
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PeerConnectionTracker* RTCPeerConnectionHandler::peer_connection_tracker() {
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return peer_connection_tracker_;
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)webrtc::SessionDescriptionInterface*
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RTCPeerConnectionHandler::CreateNativeSessionDescription(
1023f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebRTCSessionDescription& description,
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    webrtc::SdpParseError* error) {
10255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string sdp = base::UTF16ToUTF8(description.sdp());
10265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string type = base::UTF16ToUTF8(description.type());
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  webrtc::SessionDescriptionInterface* native_desc =
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dependency_factory_->CreateSessionDescription(type, sdp, error);
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG_IF(ERROR, !native_desc) << "Failed to create native session description."
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              << " Type: " << type << " SDP: " << sdp;
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return native_desc;
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
1037