• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
IncrementCounter(DataChannelCounters counter)27 void IncrementCounter(DataChannelCounters counter) {
28   UMA_HISTOGRAM_ENUMERATION("WebRTC.DataChannelCounters",
29                             counter,
30                             CHANNEL_BOUNDARY);
31 }
32 
33 }  // namespace
34 
RtcDataChannelHandler(webrtc::DataChannelInterface * channel)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 
~RtcDataChannelHandler()58 RtcDataChannelHandler::~RtcDataChannelHandler() {
59   DVLOG(1) << "::dtor";
60   channel_->UnregisterObserver();
61 }
62 
setClient(blink::WebRTCDataChannelHandlerClient * client)63 void RtcDataChannelHandler::setClient(
64     blink::WebRTCDataChannelHandlerClient* client) {
65   webkit_client_ = client;
66 }
67 
label()68 blink::WebString RtcDataChannelHandler::label() {
69   return base::UTF8ToUTF16(channel_->label());
70 }
71 
isReliable()72 bool RtcDataChannelHandler::isReliable() {
73   return channel_->reliable();
74 }
75 
ordered() const76 bool RtcDataChannelHandler::ordered() const {
77   return channel_->ordered();
78 }
79 
maxRetransmitTime() const80 unsigned short RtcDataChannelHandler::maxRetransmitTime() const {
81   return channel_->maxRetransmitTime();
82 }
83 
maxRetransmits() const84 unsigned short RtcDataChannelHandler::maxRetransmits() const {
85   return channel_->maxRetransmits();
86 }
87 
protocol() const88 blink::WebString RtcDataChannelHandler::protocol() const {
89   return base::UTF8ToUTF16(channel_->protocol());
90 }
91 
negotiated() const92 bool RtcDataChannelHandler::negotiated() const {
93   return channel_->negotiated();
94 }
95 
id() const96 unsigned short RtcDataChannelHandler::id() const {
97   return channel_->id();
98 }
99 
bufferedAmount()100 unsigned long RtcDataChannelHandler::bufferedAmount() {
101   return channel_->buffered_amount();
102 }
103 
sendStringData(const blink::WebString & data)104 bool RtcDataChannelHandler::sendStringData(const blink::WebString& data) {
105   std::string utf8_buffer = base::UTF16ToUTF8(data);
106   rtc::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 
sendRawData(const char * data,size_t length)112 bool RtcDataChannelHandler::sendRawData(const char* data, size_t length) {
113   rtc::Buffer buffer(data, length);
114   webrtc::DataBuffer data_buffer(buffer, true);
115   RecordMessageSent(data_buffer.size());
116   return channel_->Send(data_buffer);
117 }
118 
close()119 void RtcDataChannelHandler::close() {
120   channel_->Close();
121 }
122 
OnStateChange()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 
OnMessage(const webrtc::DataBuffer & buffer)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 
RecordMessageSent(size_t num_bytes)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