Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / rtc_peer_connection_handler.cc
index 6548faa..ddb07ac 100644 (file)
@@ -9,35 +9,36 @@
 #include <vector>
 
 #include "base/command_line.h"
+#include "base/debug/trace_event.h"
+#include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram.h"
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "content/public/common/content_switches.h"
-#include "content/renderer/media/media_stream_dependency_factory.h"
-#include "content/renderer/media/media_stream_source_extra_data.h"
+#include "content/renderer/media/media_stream_track.h"
 #include "content/renderer/media/peer_connection_tracker.h"
 #include "content/renderer/media/remote_media_stream_impl.h"
 #include "content/renderer/media/rtc_data_channel_handler.h"
 #include "content/renderer/media/rtc_dtmf_sender_handler.h"
 #include "content/renderer/media/rtc_media_constraints.h"
+#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_adapter.h"
 #include "content/renderer/media/webrtc_audio_capturer.h"
 #include "content/renderer/media/webrtc_audio_device_impl.h"
+#include "content/renderer/media/webrtc_uma_histograms.h"
 #include "content/renderer/render_thread_impl.h"
 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
-// TODO(hta): Move the following include to WebRTCStatsRequest.h file.
 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
-#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
 #include "third_party/WebKit/public/platform/WebRTCConfiguration.h"
 #include "third_party/WebKit/public/platform/WebRTCDataChannelInit.h"
 #include "third_party/WebKit/public/platform/WebRTCICECandidate.h"
-#include "third_party/WebKit/public/platform/WebRTCPeerConnectionHandlerClient.h"
+#include "third_party/WebKit/public/platform/WebRTCOfferOptions.h"
 #include "third_party/WebKit/public/platform/WebRTCSessionDescription.h"
 #include "third_party/WebKit/public/platform/WebRTCSessionDescriptionRequest.h"
-#include "third_party/WebKit/public/platform/WebRTCStatsRequest.h"
 #include "third_party/WebKit/public/platform/WebRTCVoidRequest.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
-#include "third_party/WebKit/public/web/WebFrame.h"
 
 namespace content {
 
@@ -129,10 +130,10 @@ CreateWebKitSessionDescription(
 
 // Converter functions from WebKit types to libjingle types.
 
-static void GetNativeIceServers(
+static void GetNativeRtcConfiguration(
     const blink::WebRTCConfiguration& server_configuration,
-    webrtc::PeerConnectionInterface::IceServers* servers) {
-  if (server_configuration.isNull() || !servers)
+    webrtc::PeerConnectionInterface::RTCConfiguration* config) {
+  if (server_configuration.isNull() || !config)
     return;
   for (size_t i = 0; i < server_configuration.numberOfServers(); ++i) {
     webrtc::PeerConnectionInterface::IceServer server;
@@ -141,7 +142,21 @@ static void GetNativeIceServers(
     server.username = base::UTF16ToUTF8(webkit_server.username());
     server.password = base::UTF16ToUTF8(webkit_server.credential());
     server.uri = webkit_server.uri().spec();
-    servers->push_back(server);
+    config->servers.push_back(server);
+  }
+
+  switch (server_configuration.iceTransports()) {
+  case blink::WebRTCIceTransportsNone:
+    config->type = webrtc::PeerConnectionInterface::kNone;
+    break;
+  case blink::WebRTCIceTransportsRelay:
+    config->type = webrtc::PeerConnectionInterface::kRelay;
+    break;
+  case blink::WebRTCIceTransportsAll:
+    config->type = webrtc::PeerConnectionInterface::kAll;
+    break;
+  default:
+    NOTREACHED();
   }
 }
 
@@ -187,6 +202,7 @@ class CreateSessionDescriptionRequest
   virtual void OnSuccess(webrtc::SessionDescriptionInterface* desc) OVERRIDE {
     tracker_.TrackOnSuccess(desc);
     webkit_request_.requestSucceeded(CreateWebKitSessionDescription(desc));
+    delete desc;
   }
   virtual void OnFailure(const std::string& error) OVERRIDE {
     tracker_.TrackOnFailure(error);
@@ -234,16 +250,26 @@ class SetSessionDescriptionRequest
 class StatsResponse : public webrtc::StatsObserver {
  public:
   explicit StatsResponse(const scoped_refptr<LocalRTCStatsRequest>& request)
-      : request_(request.get()), response_(request_->createResponse().get()) {}
+      : request_(request.get()), response_(request_->createResponse().get()) {
+    // Measure the overall time it takes to satisfy a getStats request.
+    TRACE_EVENT_ASYNC_BEGIN0("webrtc", "getStats_Native", this);
+  }
 
   virtual void OnComplete(
       const std::vector<webrtc::StatsReport>& reports) OVERRIDE {
+    TRACE_EVENT0("webrtc", "StatsResponse::OnComplete")
     for (std::vector<webrtc::StatsReport>::const_iterator it = reports.begin();
          it != reports.end(); ++it) {
       if (it->values.size() > 0) {
         AddReport(*it);
       }
     }
+
+    // Record the getSync operation as done before calling into Blink so that
+    // we don't skew the perf measurements of the native code with whatever the
+    // callback might be doing.
+    TRACE_EVENT_ASYNC_END0("webrtc", "getStats_Native", this);
+
     request_->requestSucceeded(response_);
   }
 
@@ -255,19 +281,18 @@ class StatsResponse : public webrtc::StatsObserver {
     for (webrtc::StatsReport::Values::const_iterator value_it =
          report.values.begin();
          value_it != report.values.end(); ++value_it) {
-      AddStatistic(idx, value_it->name, value_it->value);
+      AddStatistic(idx, value_it->display_name(), value_it->value);
     }
   }
 
-  void AddStatistic(int idx, const std::string& name,
-                    const std::string& value) {
+  void AddStatistic(int idx, const char* name, const std::string& value) {
     response_->addStatistic(idx,
                             blink::WebString::fromUTF8(name),
                             blink::WebString::fromUTF8(value));
   }
 
-  talk_base::scoped_refptr<LocalRTCStatsRequest> request_;
-  talk_base::scoped_refptr<LocalRTCStatsResponse> response_;
+  rtc::scoped_refptr<LocalRTCStatsRequest> request_;
+  rtc::scoped_refptr<LocalRTCStatsResponse> response_;
 };
 
 // Implementation of LocalRTCStatsRequest.
@@ -289,7 +314,7 @@ blink::WebMediaStreamTrack LocalRTCStatsRequest::component() const {
 
 scoped_refptr<LocalRTCStatsResponse> LocalRTCStatsRequest::createResponse() {
   DCHECK(!response_);
-  response_ = new talk_base::RefCountedObject<LocalRTCStatsResponse>(
+  response_ = new rtc::RefCountedObject<LocalRTCStatsResponse>(
       impl_.createResponse());
   return response_.get();
 }
@@ -316,19 +341,104 @@ void LocalRTCStatsResponse::addStatistic(size_t report,
   impl_.addStatistic(report, name, value);
 }
 
+namespace {
+
+class PeerConnectionUMAObserver : public webrtc::UMAObserver {
+ public:
+  PeerConnectionUMAObserver() {}
+  virtual ~PeerConnectionUMAObserver() {}
+
+  virtual void IncrementCounter(
+      webrtc::PeerConnectionUMAMetricsCounter counter) OVERRIDE {
+    UMA_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
+                              counter,
+                              webrtc::kBoundary);
+  }
+
+  virtual void AddHistogramSample(
+      webrtc::PeerConnectionUMAMetricsName type, int value) OVERRIDE {
+    switch (type) {
+      case webrtc::kTimeToConnect:
+        UMA_HISTOGRAM_MEDIUM_TIMES(
+            "WebRTC.PeerConnection.TimeToConnect",
+            base::TimeDelta::FromMilliseconds(value));
+        break;
+      case webrtc::kNetworkInterfaces_IPv4:
+        UMA_HISTOGRAM_COUNTS_100("WebRTC.PeerConnection.IPv4Interfaces",
+                                 value);
+        break;
+      case webrtc::kNetworkInterfaces_IPv6:
+        UMA_HISTOGRAM_COUNTS_100("WebRTC.PeerConnection.IPv6Interfaces",
+                                 value);
+        break;
+      default:
+        NOTREACHED();
+    }
+  }
+};
+
+base::LazyInstance<std::set<RTCPeerConnectionHandler*> >::Leaky
+    g_peer_connection_handlers = LAZY_INSTANCE_INITIALIZER;
+
+}  // namespace
+
 RTCPeerConnectionHandler::RTCPeerConnectionHandler(
     blink::WebRTCPeerConnectionHandlerClient* client,
-    MediaStreamDependencyFactory* dependency_factory)
-    : PeerConnectionHandlerBase(dependency_factory),
-      client_(client),
+    PeerConnectionDependencyFactory* dependency_factory)
+    : client_(client),
+      dependency_factory_(dependency_factory),
       frame_(NULL),
-      peer_connection_tracker_(NULL) {
+      peer_connection_tracker_(NULL),
+      num_data_channels_created_(0) {
+  g_peer_connection_handlers.Get().insert(this);
 }
 
 RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
+  g_peer_connection_handlers.Get().erase(this);
   if (peer_connection_tracker_)
     peer_connection_tracker_->UnregisterPeerConnection(this);
   STLDeleteValues(&remote_streams_);
+
+  UMA_HISTOGRAM_COUNTS_10000(
+      "WebRTC.NumDataChannelsPerPeerConnection", num_data_channels_created_);
+}
+
+// static
+void RTCPeerConnectionHandler::DestructAllHandlers() {
+  std::set<RTCPeerConnectionHandler*> handlers(
+      g_peer_connection_handlers.Get().begin(),
+      g_peer_connection_handlers.Get().end());
+  for (std::set<RTCPeerConnectionHandler*>::iterator handler = handlers.begin();
+       handler != handlers.end();
+       ++handler) {
+    (*handler)->client_->releasePeerConnectionHandler();
+  }
+}
+
+void RTCPeerConnectionHandler::ConvertOfferOptionsToConstraints(
+    const blink::WebRTCOfferOptions& options,
+    RTCMediaConstraints* output) {
+  output->AddMandatory(
+      webrtc::MediaConstraintsInterface::kOfferToReceiveAudio,
+      options.offerToReceiveAudio() > 0 ? "true" : "false",
+      true);
+
+  output->AddMandatory(
+      webrtc::MediaConstraintsInterface::kOfferToReceiveVideo,
+      options.offerToReceiveVideo() > 0 ? "true" : "false",
+      true);
+
+  if (!options.voiceActivityDetection()) {
+    output->AddMandatory(
+        webrtc::MediaConstraintsInterface::kVoiceActivityDetection,
+        "false",
+        true);
+  }
+
+  if (options.iceRestart()) {
+    output->AddMandatory(
+        webrtc::MediaConstraintsInterface::kIceRestart, "true", true);
+  }
 }
 
 void RTCPeerConnectionHandler::associateWithFrame(blink::WebFrame* frame) {
@@ -344,22 +454,25 @@ bool RTCPeerConnectionHandler::initialize(
   peer_connection_tracker_ =
       RenderThreadImpl::current()->peer_connection_tracker();
 
-  webrtc::PeerConnectionInterface::IceServers servers;
-  GetNativeIceServers(server_configuration, &servers);
+  webrtc::PeerConnectionInterface::RTCConfiguration config;
+  GetNativeRtcConfiguration(server_configuration, &config);
 
   RTCMediaConstraints constraints(options);
 
   native_peer_connection_ =
       dependency_factory_->CreatePeerConnection(
-          servers, &constraints, frame_, this);
+          config, &constraints, frame_, this);
+
   if (!native_peer_connection_.get()) {
     LOG(ERROR) << "Failed to initialize native PeerConnection.";
     return false;
   }
   if (peer_connection_tracker_)
     peer_connection_tracker_->RegisterPeerConnection(
-        this, servers, constraints, frame_);
+        this, config, constraints, frame_);
 
+  uma_observer_ = new rtc::RefCountedObject<PeerConnectionUMAObserver>();
+  native_peer_connection_->RegisterUMAObserver(uma_observer_.get());
   return true;
 }
 
@@ -367,13 +480,13 @@ bool RTCPeerConnectionHandler::InitializeForTest(
     const blink::WebRTCConfiguration& server_configuration,
     const blink::WebMediaConstraints& options,
     PeerConnectionTracker* peer_connection_tracker) {
-  webrtc::PeerConnectionInterface::IceServers servers;
-  GetNativeIceServers(server_configuration, &servers);
+  webrtc::PeerConnectionInterface::RTCConfiguration config;
+  GetNativeRtcConfiguration(server_configuration, &config);
 
   RTCMediaConstraints constraints(options);
   native_peer_connection_ =
       dependency_factory_->CreatePeerConnection(
-          servers, &constraints, NULL, this);
+          config, &constraints, NULL, this);
   if (!native_peer_connection_.get()) {
     LOG(ERROR) << "Failed to initialize native PeerConnection.";
     return false;
@@ -386,7 +499,7 @@ void RTCPeerConnectionHandler::createOffer(
     const blink::WebRTCSessionDescriptionRequest& request,
     const blink::WebMediaConstraints& options) {
   scoped_refptr<CreateSessionDescriptionRequest> description_request(
-      new talk_base::RefCountedObject<CreateSessionDescriptionRequest>(
+      new rtc::RefCountedObject<CreateSessionDescriptionRequest>(
           request, this, PeerConnectionTracker::ACTION_CREATE_OFFER));
   RTCMediaConstraints constraints(options);
   native_peer_connection_->CreateOffer(description_request.get(), &constraints);
@@ -395,11 +508,26 @@ void RTCPeerConnectionHandler::createOffer(
     peer_connection_tracker_->TrackCreateOffer(this, constraints);
 }
 
+void RTCPeerConnectionHandler::createOffer(
+    const blink::WebRTCSessionDescriptionRequest& request,
+    const blink::WebRTCOfferOptions& options) {
+  scoped_refptr<CreateSessionDescriptionRequest> description_request(
+      new rtc::RefCountedObject<CreateSessionDescriptionRequest>(
+          request, this, PeerConnectionTracker::ACTION_CREATE_OFFER));
+
+  RTCMediaConstraints constraints;
+  ConvertOfferOptionsToConstraints(options, &constraints);
+  native_peer_connection_->CreateOffer(description_request.get(), &constraints);
+
+  if (peer_connection_tracker_)
+    peer_connection_tracker_->TrackCreateOffer(this, constraints);
+}
+
 void RTCPeerConnectionHandler::createAnswer(
     const blink::WebRTCSessionDescriptionRequest& request,
     const blink::WebMediaConstraints& options) {
   scoped_refptr<CreateSessionDescriptionRequest> description_request(
-      new talk_base::RefCountedObject<CreateSessionDescriptionRequest>(
+      new rtc::RefCountedObject<CreateSessionDescriptionRequest>(
           request, this, PeerConnectionTracker::ACTION_CREATE_ANSWER));
   RTCMediaConstraints constraints(options);
   native_peer_connection_->CreateAnswer(description_request.get(),
@@ -429,7 +557,7 @@ void RTCPeerConnectionHandler::setLocalDescription(
         this, description, PeerConnectionTracker::SOURCE_LOCAL);
 
   scoped_refptr<SetSessionDescriptionRequest> set_request(
-      new talk_base::RefCountedObject<SetSessionDescriptionRequest>(
+      new rtc::RefCountedObject<SetSessionDescriptionRequest>(
           request, this, PeerConnectionTracker::ACTION_SET_LOCAL_DESCRIPTION));
   native_peer_connection_->SetLocalDescription(set_request.get(), native_desc);
 }
@@ -454,7 +582,7 @@ void RTCPeerConnectionHandler::setRemoteDescription(
         this, description, PeerConnectionTracker::SOURCE_REMOTE);
 
   scoped_refptr<SetSessionDescriptionRequest> set_request(
-      new talk_base::RefCountedObject<SetSessionDescriptionRequest>(
+      new rtc::RefCountedObject<SetSessionDescriptionRequest>(
           request, this, PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION));
   native_peer_connection_->SetRemoteDescription(set_request.get(), native_desc);
 }
@@ -480,14 +608,14 @@ RTCPeerConnectionHandler::remoteDescription() {
 bool RTCPeerConnectionHandler::updateICE(
     const blink::WebRTCConfiguration& server_configuration,
     const blink::WebMediaConstraints& options) {
-  webrtc::PeerConnectionInterface::IceServers servers;
-  GetNativeIceServers(server_configuration, &servers);
+  webrtc::PeerConnectionInterface::RTCConfiguration config;
+  GetNativeRtcConfiguration(server_configuration, &config);
   RTCMediaConstraints constraints(options);
 
   if (peer_connection_tracker_)
-    peer_connection_tracker_->TrackUpdateIce(this, servers, constraints);
+    peer_connection_tracker_->TrackUpdateIce(this, config, constraints);
 
-  return native_peer_connection_->UpdateIce(servers,
+  return native_peer_connection_->UpdateIce(config.servers,
                                             &constraints);
 }
 
@@ -543,50 +671,90 @@ void RTCPeerConnectionHandler::OnaddICECandidateResult(
 bool RTCPeerConnectionHandler::addStream(
     const blink::WebMediaStream& stream,
     const blink::WebMediaConstraints& options) {
-  RTCMediaConstraints constraints(options);
+
+  for (ScopedVector<WebRtcMediaStreamAdapter>::iterator adapter_it =
+      local_streams_.begin(); adapter_it != local_streams_.end();
+      ++adapter_it) {
+    if ((*adapter_it)->IsEqual(stream)) {
+      DVLOG(1) << "RTCPeerConnectionHandler::addStream called with the same "
+               << "stream twice. id=" << stream.id().utf8();
+      return false;
+    }
+  }
 
   if (peer_connection_tracker_)
     peer_connection_tracker_->TrackAddStream(
         this, stream, PeerConnectionTracker::SOURCE_LOCAL);
 
-  // A media stream is connected to a peer connection, enable the
-  // peer connection mode for the sources.
-  blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
-  stream.audioTracks(audio_tracks);
-  for (size_t i = 0; i < audio_tracks.size(); ++i) {
-    const blink::WebMediaStreamSource& source = audio_tracks[i].source();
-    MediaStreamSourceExtraData* extra_data =
-        static_cast<MediaStreamSourceExtraData*>(source.extraData());
-    // |extra_data| is NULL if the track is a remote audio track.
-    if (extra_data && extra_data->GetAudioCapturer())
-      extra_data->GetAudioCapturer()->EnablePeerConnectionMode();
-  }
+  PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter();
+
+  WebRtcMediaStreamAdapter* adapter =
+      new WebRtcMediaStreamAdapter(stream, dependency_factory_);
+  local_streams_.push_back(adapter);
+
+  webrtc::MediaStreamInterface* webrtc_stream = adapter->webrtc_media_stream();
+  track_metrics_.AddStream(MediaStreamTrackMetrics::SENT_STREAM,
+                           webrtc_stream);
 
-  return AddStream(stream, &constraints);
+  RTCMediaConstraints constraints(options);
+  return native_peer_connection_->AddStream(webrtc_stream, &constraints);
 }
 
 void RTCPeerConnectionHandler::removeStream(
     const blink::WebMediaStream& stream) {
-  RemoveStream(stream);
+  // Find the webrtc stream.
+  scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream;
+  for (ScopedVector<WebRtcMediaStreamAdapter>::iterator adapter_it =
+           local_streams_.begin(); adapter_it != local_streams_.end();
+       ++adapter_it) {
+    if ((*adapter_it)->IsEqual(stream)) {
+      webrtc_stream = (*adapter_it)->webrtc_media_stream();
+      local_streams_.erase(adapter_it);
+      break;
+    }
+  }
+  DCHECK(webrtc_stream);
+  native_peer_connection_->RemoveStream(webrtc_stream);
+
   if (peer_connection_tracker_)
     peer_connection_tracker_->TrackRemoveStream(
         this, stream, PeerConnectionTracker::SOURCE_LOCAL);
+  PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter();
+  track_metrics_.RemoveStream(MediaStreamTrackMetrics::SENT_STREAM,
+                              webrtc_stream);
 }
 
 void RTCPeerConnectionHandler::getStats(
     const blink::WebRTCStatsRequest& request) {
   scoped_refptr<LocalRTCStatsRequest> inner_request(
-      new talk_base::RefCountedObject<LocalRTCStatsRequest>(request));
+      new rtc::RefCountedObject<LocalRTCStatsRequest>(request));
   getStats(inner_request.get());
 }
 
 void RTCPeerConnectionHandler::getStats(LocalRTCStatsRequest* request) {
-  talk_base::scoped_refptr<webrtc::StatsObserver> observer(
-      new talk_base::RefCountedObject<StatsResponse>(request));
+  rtc::scoped_refptr<webrtc::StatsObserver> observer(
+      new rtc::RefCountedObject<StatsResponse>(request));
   webrtc::MediaStreamTrackInterface* track = NULL;
   if (request->hasSelector()) {
-      track = MediaStreamDependencyFactory::GetNativeMediaStreamTrack(
-          request->component());
+    blink::WebMediaStreamSource::Type type =
+        request->component().source().type();
+    std::string track_id = request->component().id().utf8();
+    if (type == blink::WebMediaStreamSource::TypeAudio) {
+      track =
+          native_peer_connection_->local_streams()->FindAudioTrack(track_id);
+      if (!track) {
+        track =
+            native_peer_connection_->remote_streams()->FindAudioTrack(track_id);
+      }
+    } else {
+      DCHECK_EQ(blink::WebMediaStreamSource::TypeVideo, type);
+      track =
+          native_peer_connection_->local_streams()->FindVideoTrack(track_id);
+      if (!track) {
+        track =
+            native_peer_connection_->remote_streams()->FindVideoTrack(track_id);
+      }
+    }
     if (!track) {
       DVLOG(1) << "GetStats: Track not found.";
       // TODO(hta): Consider how to get an error back.
@@ -595,13 +763,17 @@ void RTCPeerConnectionHandler::getStats(LocalRTCStatsRequest* request) {
       return;
     }
   }
-  GetStats(observer, track);
+  GetStats(observer,
+           track,
+           webrtc::PeerConnectionInterface::kStatsOutputLevelStandard);
 }
 
 void RTCPeerConnectionHandler::GetStats(
     webrtc::StatsObserver* observer,
-    webrtc::MediaStreamTrackInterface* track) {
-  if (!native_peer_connection_->GetStats(observer, track)) {
+    webrtc::MediaStreamTrackInterface* track,
+    webrtc::PeerConnectionInterface::StatsOutputLevel level) {
+  TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::GetStats");
+  if (!native_peer_connection_->GetStats(observer, track, level)) {
     DVLOG(1) << "GetStats failed.";
     // TODO(hta): Consider how to get an error back.
     std::vector<webrtc::StatsReport> no_reports;
@@ -625,7 +797,7 @@ blink::WebRTCDataChannelHandler* RTCPeerConnectionHandler::createDataChannel(
   config.maxRetransmitTime = init.maxRetransmitTime;
   config.protocol = base::UTF16ToUTF8(init.protocol);
 
-  talk_base::scoped_refptr<webrtc::DataChannelInterface> webrtc_channel(
+  rtc::scoped_refptr<webrtc::DataChannelInterface> webrtc_channel(
       native_peer_connection_->CreateDataChannel(base::UTF16ToUTF8(label),
                                                  &config));
   if (!webrtc_channel) {
@@ -636,6 +808,8 @@ blink::WebRTCDataChannelHandler* RTCPeerConnectionHandler::createDataChannel(
     peer_connection_tracker_->TrackCreateDataChannel(
         this, webrtc_channel.get(), PeerConnectionTracker::SOURCE_LOCAL);
 
+  ++num_data_channels_created_;
+
   return new RtcDataChannelHandler(webrtc_channel);
 }
 
@@ -643,16 +817,15 @@ blink::WebRTCDTMFSenderHandler* RTCPeerConnectionHandler::createDTMFSender(
     const blink::WebMediaStreamTrack& track) {
   DVLOG(1) << "createDTMFSender.";
 
-  if (track.source().type() != blink::WebMediaStreamSource::TypeAudio) {
+  MediaStreamTrack* native_track = MediaStreamTrack::GetTrack(track);
+  if (!native_track ||
+      track.source().type() != blink::WebMediaStreamSource::TypeAudio) {
     DLOG(ERROR) << "Could not create DTMF sender from a non-audio track.";
     return NULL;
   }
 
-  webrtc::AudioTrackInterface* audio_track =
-      static_cast<webrtc::AudioTrackInterface*>(
-          MediaStreamDependencyFactory::GetNativeMediaStreamTrack(track));
-
-  talk_base::scoped_refptr<webrtc::DtmfSenderInterface> sender(
+  webrtc::AudioTrackInterface* audio_track = native_track->GetAudioAdapter();
+  rtc::scoped_refptr<webrtc::DtmfSenderInterface> sender(
       native_peer_connection_->CreateDtmfSender(audio_track));
   if (!sender) {
     DLOG(ERROR) << "Could not create native DTMF sender.";
@@ -689,6 +862,19 @@ void RTCPeerConnectionHandler::OnSignalingChange(
 // Called any time the IceConnectionState changes
 void RTCPeerConnectionHandler::OnIceConnectionChange(
     webrtc::PeerConnectionInterface::IceConnectionState new_state) {
+  if (new_state == webrtc::PeerConnectionInterface::kIceConnectionChecking) {
+    ice_connection_checking_start_ = base::TimeTicks::Now();
+  } else if (new_state ==
+      webrtc::PeerConnectionInterface::kIceConnectionConnected) {
+    // If the state becomes connected, send the time needed for PC to become
+    // connected from checking to UMA. UMA data will help to know how much
+    // time needed for PC to connect with remote peer.
+    UMA_HISTOGRAM_MEDIUM_TIMES(
+        "WebRTC.PeerConnection.TimeToConnect",
+        base::TimeTicks::Now() - ice_connection_checking_start_);
+  }
+
+  track_metrics_.IceConnectionChange(new_state);
   blink::WebRTCPeerConnectionHandlerClient::ICEConnectionState state =
       GetWebKitIceConnectionState(new_state);
   if (peer_connection_tracker_)
@@ -729,6 +915,11 @@ void RTCPeerConnectionHandler::OnAddStream(
         this, remote_stream->webkit_stream(),
         PeerConnectionTracker::SOURCE_REMOTE);
 
+  PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter();
+
+  track_metrics_.AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM,
+                           stream_interface);
+
   client_->didAddRemoteStream(remote_stream->webkit_stream());
 }
 
@@ -741,6 +932,10 @@ void RTCPeerConnectionHandler::OnRemoveStream(
     return;
   }
 
+  track_metrics_.RemoveStream(MediaStreamTrackMetrics::RECEIVED_STREAM,
+                              stream_interface);
+  PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter();
+
   scoped_ptr<RemoteMediaStreamImpl> remote_stream(it->second);
   const blink::WebMediaStream& webkit_stream = remote_stream->webkit_stream();
   DCHECK(!webkit_stream.isNull());