Home | History | Annotate | Download | only in media
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/renderer/media/rtc_data_channel_handler.h"
      6 
      7 #include <limits>
      8 #include <string>
      9 
     10 #include "base/logging.h"
     11 #include "base/metrics/histogram.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 
     14 namespace content {
     15 
     16 namespace {
     17 
     18 enum DataChannelCounters {
     19   CHANNEL_CREATED,
     20   CHANNEL_OPENED,
     21   CHANNEL_RELIABLE,
     22   CHANNEL_ORDERED,
     23   CHANNEL_NEGOTIATED,
     24   CHANNEL_BOUNDARY
     25 };
     26 
     27 void IncrementCounter(DataChannelCounters counter) {
     28   UMA_HISTOGRAM_ENUMERATION("WebRTC.DataChannelCounters",
     29                             counter,
     30                             CHANNEL_BOUNDARY);
     31 }
     32 
     33 }  // namespace
     34 
     35 RtcDataChannelHandler::RtcDataChannelHandler(
     36     webrtc::DataChannelInterface* channel)
     37     : channel_(channel),
     38       webkit_client_(NULL) {
     39   DVLOG(1) << "::ctor";
     40   channel_->RegisterObserver(this);
     41 
     42   IncrementCounter(CHANNEL_CREATED);
     43   if (isReliable())
     44     IncrementCounter(CHANNEL_RELIABLE);
     45   if (ordered())
     46     IncrementCounter(CHANNEL_ORDERED);
     47   if (negotiated())
     48     IncrementCounter(CHANNEL_NEGOTIATED);
     49 
     50   UMA_HISTOGRAM_CUSTOM_COUNTS("WebRTC.DataChannelMaxRetransmits",
     51                               maxRetransmits(), 0,
     52                               std::numeric_limits<unsigned short>::max(), 50);
     53   UMA_HISTOGRAM_CUSTOM_COUNTS("WebRTC.DataChannelMaxRetransmitTime",
     54                               maxRetransmitTime(), 0,
     55                               std::numeric_limits<unsigned short>::max(), 50);
     56 }
     57 
     58 RtcDataChannelHandler::~RtcDataChannelHandler() {
     59   DVLOG(1) << "::dtor";
     60   channel_->UnregisterObserver();
     61 }
     62 
     63 void RtcDataChannelHandler::setClient(
     64     blink::WebRTCDataChannelHandlerClient* client) {
     65   webkit_client_ = client;
     66 }
     67 
     68 blink::WebString RtcDataChannelHandler::label() {
     69   return base::UTF8ToUTF16(channel_->label());
     70 }
     71 
     72 bool RtcDataChannelHandler::isReliable() {
     73   return channel_->reliable();
     74 }
     75 
     76 bool RtcDataChannelHandler::ordered() const {
     77   return channel_->ordered();
     78 }
     79 
     80 unsigned short RtcDataChannelHandler::maxRetransmitTime() const {
     81   return channel_->maxRetransmitTime();
     82 }
     83 
     84 unsigned short RtcDataChannelHandler::maxRetransmits() const {
     85   return channel_->maxRetransmits();
     86 }
     87 
     88 blink::WebString RtcDataChannelHandler::protocol() const {
     89   return base::UTF8ToUTF16(channel_->protocol());
     90 }
     91 
     92 bool RtcDataChannelHandler::negotiated() const {
     93   return channel_->negotiated();
     94 }
     95 
     96 unsigned short RtcDataChannelHandler::id() const {
     97   return channel_->id();
     98 }
     99 
    100 unsigned long RtcDataChannelHandler::bufferedAmount() {
    101   return channel_->buffered_amount();
    102 }
    103 
    104 bool RtcDataChannelHandler::sendStringData(const blink::WebString& data) {
    105   std::string utf8_buffer = base::UTF16ToUTF8(data);
    106   talk_base::Buffer buffer(utf8_buffer.c_str(), utf8_buffer.length());
    107   webrtc::DataBuffer data_buffer(buffer, false);
    108   RecordMessageSent(data_buffer.size());
    109   return channel_->Send(data_buffer);
    110 }
    111 
    112 bool RtcDataChannelHandler::sendRawData(const char* data, size_t length) {
    113   talk_base::Buffer buffer(data, length);
    114   webrtc::DataBuffer data_buffer(buffer, true);
    115   RecordMessageSent(data_buffer.size());
    116   return channel_->Send(data_buffer);
    117 }
    118 
    119 void RtcDataChannelHandler::close() {
    120   channel_->Close();
    121 }
    122 
    123 void RtcDataChannelHandler::OnStateChange() {
    124   if (!webkit_client_) {
    125     LOG(ERROR) << "WebRTCDataChannelHandlerClient not set.";
    126     return;
    127   }
    128   DVLOG(1) << "OnStateChange " << channel_->state();
    129   switch (channel_->state()) {
    130     case webrtc::DataChannelInterface::kConnecting:
    131       webkit_client_->didChangeReadyState(
    132           blink::WebRTCDataChannelHandlerClient::ReadyStateConnecting);
    133       break;
    134     case webrtc::DataChannelInterface::kOpen:
    135       IncrementCounter(CHANNEL_OPENED);
    136       webkit_client_->didChangeReadyState(
    137           blink::WebRTCDataChannelHandlerClient::ReadyStateOpen);
    138       break;
    139     case webrtc::DataChannelInterface::kClosing:
    140       webkit_client_->didChangeReadyState(
    141           blink::WebRTCDataChannelHandlerClient::ReadyStateClosing);
    142       break;
    143     case webrtc::DataChannelInterface::kClosed:
    144       webkit_client_->didChangeReadyState(
    145           blink::WebRTCDataChannelHandlerClient::ReadyStateClosed);
    146       break;
    147     default:
    148       NOTREACHED();
    149       break;
    150   }
    151 }
    152 
    153 void RtcDataChannelHandler::OnMessage(const webrtc::DataBuffer& buffer) {
    154   if (!webkit_client_) {
    155     LOG(ERROR) << "WebRTCDataChannelHandlerClient not set.";
    156     return;
    157   }
    158 
    159   if (buffer.binary) {
    160     webkit_client_->didReceiveRawData(buffer.data.data(), buffer.data.length());
    161   } else {
    162     base::string16 utf16;
    163     if (!base::UTF8ToUTF16(buffer.data.data(), buffer.data.length(), &utf16)) {
    164       LOG(ERROR) << "Failed convert received data to UTF16";
    165       return;
    166     }
    167     webkit_client_->didReceiveStringData(utf16);
    168   }
    169 }
    170 
    171 void RtcDataChannelHandler::RecordMessageSent(size_t num_bytes) {
    172   // Currently, messages are capped at some fairly low limit (16 Kb?)
    173   // but we may allow unlimited-size messages at some point, so making
    174   // the histogram maximum quite large (100 Mb) to have some
    175   // granularity at the higher end in that eventuality. The histogram
    176   // buckets are exponentially growing in size, so we'll still have
    177   // good granularity at the low end.
    178 
    179   // This makes the last bucket in the histogram count messages from
    180   // 100 Mb to infinity.
    181   const int kMaxBucketSize = 100 * 1024 * 1024;
    182   const int kNumBuckets = 50;
    183 
    184   if (isReliable()) {
    185     UMA_HISTOGRAM_CUSTOM_COUNTS("WebRTC.ReliableDataChannelMessageSize",
    186                                 num_bytes,
    187                                 1, kMaxBucketSize, kNumBuckets);
    188   } else {
    189     UMA_HISTOGRAM_CUSTOM_COUNTS("WebRTC.UnreliableDataChannelMessageSize",
    190                                 num_bytes,
    191                                 1, kMaxBucketSize, kNumBuckets);
    192   }
    193 }
    194 
    195 }  // namespace content
    196