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