Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: content/renderer/media/rtc_data_channel_handler.cc

Issue 689783002: Refactor RtcDataChannelHandler. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/rtc_data_channel_handler.h" 5 #include "content/renderer/media/rtc_data_channel_handler.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h"
11 #include "base/location.h"
10 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/message_loop/message_loop.h"
11 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
12 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #include "base/thread_task_runner_handle.h"
13 17
14 namespace content { 18 namespace content {
15 19
16 namespace { 20 namespace {
17 21
18 enum DataChannelCounters { 22 enum DataChannelCounters {
19 CHANNEL_CREATED, 23 CHANNEL_CREATED,
20 CHANNEL_OPENED, 24 CHANNEL_OPENED,
21 CHANNEL_RELIABLE, 25 CHANNEL_RELIABLE,
22 CHANNEL_ORDERED, 26 CHANNEL_ORDERED,
23 CHANNEL_NEGOTIATED, 27 CHANNEL_NEGOTIATED,
24 CHANNEL_BOUNDARY 28 CHANNEL_BOUNDARY
25 }; 29 };
26 30
27 void IncrementCounter(DataChannelCounters counter) { 31 void IncrementCounter(DataChannelCounters counter) {
28 UMA_HISTOGRAM_ENUMERATION("WebRTC.DataChannelCounters", 32 UMA_HISTOGRAM_ENUMERATION("WebRTC.DataChannelCounters",
29 counter, 33 counter,
30 CHANNEL_BOUNDARY); 34 CHANNEL_BOUNDARY);
31 } 35 }
32 36
33 } // namespace 37 } // namespace
34 38
39 // Implementation of DataChannelObserver that receives events on libjingle's
40 // signaling thread and forwards them over to the main thread for handling.
41 // Since the handler's lifetime is scoped potentially narrower than what
42 // the callbacks allow for, we use reference counting here to make sure
43 // all callbacks have a valid pointer but won't do anything if the handler
44 // has gone away.
45 RtcDataChannelHandler::Observer::Observer(
46 RtcDataChannelHandler* handler,
47 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
48 webrtc::DataChannelInterface* channel)
49 : handler_(handler), main_thread_(main_thread), channel_(channel) {
50 channel_->RegisterObserver(this);
51 }
52
53 RtcDataChannelHandler::Observer::~Observer() {}
54
55 const scoped_refptr<base::SingleThreadTaskRunner>&
56 RtcDataChannelHandler::Observer::main_thread() const {
57 return main_thread_;
58 }
59
60 const scoped_refptr<webrtc::DataChannelInterface>&
61 RtcDataChannelHandler::Observer::channel() const {
62 return channel_;
63 }
64
65 void RtcDataChannelHandler::Observer::ClearHandler() {
66 DCHECK(main_thread_->BelongsToCurrentThread());
67 handler_ = nullptr;
68 }
69
70 void RtcDataChannelHandler::Observer::OnStateChange() {
71 main_thread_->PostTask(FROM_HERE, base::Bind(
72 &RtcDataChannelHandler::Observer::OnStateChangeImpl, this,
73 channel_->state()));
74 }
75
76 void RtcDataChannelHandler::Observer::OnMessage(
77 const webrtc::DataBuffer& buffer) {
78 // TODO(tommi): Figure out a way to transfer ownership of the buffer without
79 // having to create a copy. See webrtc bug 3967.
80 scoped_ptr<webrtc::DataBuffer> new_buffer(new webrtc::DataBuffer(buffer));
81 main_thread_->PostTask(FROM_HERE,
82 base::Bind(&RtcDataChannelHandler::Observer::OnMessageImpl, this,
83 base::Passed(&new_buffer)));
84 }
85
86 void RtcDataChannelHandler::Observer::OnStateChangeImpl(
87 webrtc::DataChannelInterface::DataState state) {
88 DCHECK(main_thread_->BelongsToCurrentThread());
89 if (handler_)
90 handler_->OnStateChange(state);
91 }
92
93 void RtcDataChannelHandler::Observer::OnMessageImpl(
94 scoped_ptr<webrtc::DataBuffer> buffer) {
95 DCHECK(main_thread_->BelongsToCurrentThread());
96 if (handler_)
97 handler_->OnMessage(buffer.Pass());
98 }
99
35 RtcDataChannelHandler::RtcDataChannelHandler( 100 RtcDataChannelHandler::RtcDataChannelHandler(
101 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
36 webrtc::DataChannelInterface* channel) 102 webrtc::DataChannelInterface* channel)
37 : channel_(channel), 103 : observer_(new Observer(this, main_thread, channel)),
38 webkit_client_(NULL) { 104 webkit_client_(NULL) {
39 DVLOG(1) << "::ctor"; 105 DVLOG(1) << "RtcDataChannelHandler " << channel->label();
40 channel_->RegisterObserver(this); 106
107 // Detach from the ctor thread since we can be constructed on either the main
108 // or signaling threads.
109 thread_checker_.DetachFromThread();
41 110
42 IncrementCounter(CHANNEL_CREATED); 111 IncrementCounter(CHANNEL_CREATED);
43 if (isReliable()) 112 if (channel->reliable())
44 IncrementCounter(CHANNEL_RELIABLE); 113 IncrementCounter(CHANNEL_RELIABLE);
45 if (ordered()) 114 if (channel->ordered())
46 IncrementCounter(CHANNEL_ORDERED); 115 IncrementCounter(CHANNEL_ORDERED);
47 if (negotiated()) 116 if (channel->negotiated())
48 IncrementCounter(CHANNEL_NEGOTIATED); 117 IncrementCounter(CHANNEL_NEGOTIATED);
49 118
50 UMA_HISTOGRAM_CUSTOM_COUNTS("WebRTC.DataChannelMaxRetransmits", 119 UMA_HISTOGRAM_CUSTOM_COUNTS("WebRTC.DataChannelMaxRetransmits",
51 maxRetransmits(), 0, 120 channel->maxRetransmits(), 0,
52 std::numeric_limits<unsigned short>::max(), 50); 121 std::numeric_limits<unsigned short>::max(), 50);
53 UMA_HISTOGRAM_CUSTOM_COUNTS("WebRTC.DataChannelMaxRetransmitTime", 122 UMA_HISTOGRAM_CUSTOM_COUNTS("WebRTC.DataChannelMaxRetransmitTime",
54 maxRetransmitTime(), 0, 123 channel->maxRetransmitTime(), 0,
55 std::numeric_limits<unsigned short>::max(), 50); 124 std::numeric_limits<unsigned short>::max(), 50);
56 } 125 }
57 126
58 RtcDataChannelHandler::~RtcDataChannelHandler() { 127 RtcDataChannelHandler::~RtcDataChannelHandler() {
128 DCHECK(thread_checker_.CalledOnValidThread());
59 DVLOG(1) << "::dtor"; 129 DVLOG(1) << "::dtor";
60 channel_->UnregisterObserver(); 130 observer_->ClearHandler();
61 } 131 }
62 132
63 void RtcDataChannelHandler::setClient( 133 void RtcDataChannelHandler::setClient(
64 blink::WebRTCDataChannelHandlerClient* client) { 134 blink::WebRTCDataChannelHandlerClient* client) {
135 DCHECK(thread_checker_.CalledOnValidThread());
65 webkit_client_ = client; 136 webkit_client_ = client;
66 } 137 }
67 138
68 blink::WebString RtcDataChannelHandler::label() { 139 blink::WebString RtcDataChannelHandler::label() {
69 return base::UTF8ToUTF16(channel_->label()); 140 DCHECK(thread_checker_.CalledOnValidThread());
141 return base::UTF8ToUTF16(channel()->label());
70 } 142 }
71 143
72 bool RtcDataChannelHandler::isReliable() { 144 bool RtcDataChannelHandler::isReliable() {
73 return channel_->reliable(); 145 DCHECK(thread_checker_.CalledOnValidThread());
146 return channel()->reliable();
74 } 147 }
75 148
76 bool RtcDataChannelHandler::ordered() const { 149 bool RtcDataChannelHandler::ordered() const {
77 return channel_->ordered(); 150 DCHECK(thread_checker_.CalledOnValidThread());
151 return channel()->ordered();
78 } 152 }
79 153
80 unsigned short RtcDataChannelHandler::maxRetransmitTime() const { 154 unsigned short RtcDataChannelHandler::maxRetransmitTime() const {
81 return channel_->maxRetransmitTime(); 155 DCHECK(thread_checker_.CalledOnValidThread());
156 return channel()->maxRetransmitTime();
82 } 157 }
83 158
84 unsigned short RtcDataChannelHandler::maxRetransmits() const { 159 unsigned short RtcDataChannelHandler::maxRetransmits() const {
85 return channel_->maxRetransmits(); 160 DCHECK(thread_checker_.CalledOnValidThread());
161 return channel()->maxRetransmits();
86 } 162 }
87 163
88 blink::WebString RtcDataChannelHandler::protocol() const { 164 blink::WebString RtcDataChannelHandler::protocol() const {
89 return base::UTF8ToUTF16(channel_->protocol()); 165 DCHECK(thread_checker_.CalledOnValidThread());
166 return base::UTF8ToUTF16(channel()->protocol());
90 } 167 }
91 168
92 bool RtcDataChannelHandler::negotiated() const { 169 bool RtcDataChannelHandler::negotiated() const {
93 return channel_->negotiated(); 170 DCHECK(thread_checker_.CalledOnValidThread());
171 return channel()->negotiated();
94 } 172 }
95 173
96 unsigned short RtcDataChannelHandler::id() const { 174 unsigned short RtcDataChannelHandler::id() const {
97 return channel_->id(); 175 DCHECK(thread_checker_.CalledOnValidThread());
176 return channel()->id();
98 } 177 }
99 178
100 unsigned long RtcDataChannelHandler::bufferedAmount() { 179 unsigned long RtcDataChannelHandler::bufferedAmount() {
101 return channel_->buffered_amount(); 180 DCHECK(thread_checker_.CalledOnValidThread());
181 return channel()->buffered_amount();
102 } 182 }
103 183
104 bool RtcDataChannelHandler::sendStringData(const blink::WebString& data) { 184 bool RtcDataChannelHandler::sendStringData(const blink::WebString& data) {
185 DCHECK(thread_checker_.CalledOnValidThread());
105 std::string utf8_buffer = base::UTF16ToUTF8(data); 186 std::string utf8_buffer = base::UTF16ToUTF8(data);
106 rtc::Buffer buffer(utf8_buffer.c_str(), utf8_buffer.length()); 187 rtc::Buffer buffer(utf8_buffer.c_str(), utf8_buffer.length());
107 webrtc::DataBuffer data_buffer(buffer, false); 188 webrtc::DataBuffer data_buffer(buffer, false);
108 RecordMessageSent(data_buffer.size()); 189 RecordMessageSent(data_buffer.size());
109 return channel_->Send(data_buffer); 190 return channel()->Send(data_buffer);
110 } 191 }
111 192
112 bool RtcDataChannelHandler::sendRawData(const char* data, size_t length) { 193 bool RtcDataChannelHandler::sendRawData(const char* data, size_t length) {
194 DCHECK(thread_checker_.CalledOnValidThread());
113 rtc::Buffer buffer(data, length); 195 rtc::Buffer buffer(data, length);
114 webrtc::DataBuffer data_buffer(buffer, true); 196 webrtc::DataBuffer data_buffer(buffer, true);
115 RecordMessageSent(data_buffer.size()); 197 RecordMessageSent(data_buffer.size());
116 return channel_->Send(data_buffer); 198 return channel()->Send(data_buffer);
117 } 199 }
118 200
119 void RtcDataChannelHandler::close() { 201 void RtcDataChannelHandler::close() {
120 channel_->Close(); 202 DCHECK(thread_checker_.CalledOnValidThread());
203 channel()->Close();
204 // Note that even though Close() will run synchronously, the readyState has
205 // not changed yet since the state changes that occured on the signaling
206 // thread have been posted to this thread and will be delivered later.
207 // To work around this, we could have a nested loop here and deliver the
208 // callbacks before running from this function, but doing so can cause
209 // undesired side effects in webkit, so we don't, and instead rely on the
210 // user of the API handling readyState notifications.
121 } 211 }
122 212
123 void RtcDataChannelHandler::OnStateChange() { 213 const scoped_refptr<webrtc::DataChannelInterface>&
214 RtcDataChannelHandler::channel() const {
215 return observer_->channel();
216 }
217
218 void RtcDataChannelHandler::OnStateChange(
219 webrtc::DataChannelInterface::DataState state) {
220 DCHECK(thread_checker_.CalledOnValidThread());
221 DVLOG(1) << "OnStateChange " << state;
222
124 if (!webkit_client_) { 223 if (!webkit_client_) {
125 LOG(ERROR) << "WebRTCDataChannelHandlerClient not set."; 224 // If this happens, the web application will not get notified of changes.
225 NOTREACHED() << "WebRTCDataChannelHandlerClient not set.";
126 return; 226 return;
127 } 227 }
128 DVLOG(1) << "OnStateChange " << channel_->state(); 228
129 switch (channel_->state()) { 229 switch (state) {
130 case webrtc::DataChannelInterface::kConnecting: 230 case webrtc::DataChannelInterface::kConnecting:
131 webkit_client_->didChangeReadyState( 231 webkit_client_->didChangeReadyState(
132 blink::WebRTCDataChannelHandlerClient::ReadyStateConnecting); 232 blink::WebRTCDataChannelHandlerClient::ReadyStateConnecting);
133 break; 233 break;
134 case webrtc::DataChannelInterface::kOpen: 234 case webrtc::DataChannelInterface::kOpen:
135 IncrementCounter(CHANNEL_OPENED); 235 IncrementCounter(CHANNEL_OPENED);
136 webkit_client_->didChangeReadyState( 236 webkit_client_->didChangeReadyState(
137 blink::WebRTCDataChannelHandlerClient::ReadyStateOpen); 237 blink::WebRTCDataChannelHandlerClient::ReadyStateOpen);
138 break; 238 break;
139 case webrtc::DataChannelInterface::kClosing: 239 case webrtc::DataChannelInterface::kClosing:
140 webkit_client_->didChangeReadyState( 240 webkit_client_->didChangeReadyState(
141 blink::WebRTCDataChannelHandlerClient::ReadyStateClosing); 241 blink::WebRTCDataChannelHandlerClient::ReadyStateClosing);
142 break; 242 break;
143 case webrtc::DataChannelInterface::kClosed: 243 case webrtc::DataChannelInterface::kClosed:
144 webkit_client_->didChangeReadyState( 244 webkit_client_->didChangeReadyState(
145 blink::WebRTCDataChannelHandlerClient::ReadyStateClosed); 245 blink::WebRTCDataChannelHandlerClient::ReadyStateClosed);
146 break; 246 break;
147 default: 247 default:
148 NOTREACHED(); 248 NOTREACHED();
149 break; 249 break;
150 } 250 }
151 } 251 }
152 252
153 void RtcDataChannelHandler::OnMessage(const webrtc::DataBuffer& buffer) { 253 void RtcDataChannelHandler::OnMessage(scoped_ptr<webrtc::DataBuffer> buffer) {
254 DCHECK(thread_checker_.CalledOnValidThread());
154 if (!webkit_client_) { 255 if (!webkit_client_) {
155 LOG(ERROR) << "WebRTCDataChannelHandlerClient not set."; 256 // If this happens, the web application will not get notified of changes.
257 NOTREACHED() << "WebRTCDataChannelHandlerClient not set.";
156 return; 258 return;
157 } 259 }
158 260
159 if (buffer.binary) { 261 if (buffer->binary) {
160 webkit_client_->didReceiveRawData(buffer.data.data(), buffer.data.length()); 262 webkit_client_->didReceiveRawData(buffer->data.data(),
263 buffer->data.length());
161 } else { 264 } else {
162 base::string16 utf16; 265 base::string16 utf16;
163 if (!base::UTF8ToUTF16(buffer.data.data(), buffer.data.length(), &utf16)) { 266 if (!base::UTF8ToUTF16(buffer->data.data(), buffer->data.length(),
267 &utf16)) {
164 LOG(ERROR) << "Failed convert received data to UTF16"; 268 LOG(ERROR) << "Failed convert received data to UTF16";
165 return; 269 return;
166 } 270 }
167 webkit_client_->didReceiveStringData(utf16); 271 webkit_client_->didReceiveStringData(utf16);
168 } 272 }
169 } 273 }
170 274
171 void RtcDataChannelHandler::RecordMessageSent(size_t num_bytes) { 275 void RtcDataChannelHandler::RecordMessageSent(size_t num_bytes) {
172 // Currently, messages are capped at some fairly low limit (16 Kb?) 276 // Currently, messages are capped at some fairly low limit (16 Kb?)
173 // but we may allow unlimited-size messages at some point, so making 277 // but we may allow unlimited-size messages at some point, so making
174 // the histogram maximum quite large (100 Mb) to have some 278 // the histogram maximum quite large (100 Mb) to have some
175 // granularity at the higher end in that eventuality. The histogram 279 // granularity at the higher end in that eventuality. The histogram
176 // buckets are exponentially growing in size, so we'll still have 280 // buckets are exponentially growing in size, so we'll still have
177 // good granularity at the low end. 281 // good granularity at the low end.
178 282
179 // This makes the last bucket in the histogram count messages from 283 // This makes the last bucket in the histogram count messages from
180 // 100 Mb to infinity. 284 // 100 Mb to infinity.
181 const int kMaxBucketSize = 100 * 1024 * 1024; 285 const int kMaxBucketSize = 100 * 1024 * 1024;
182 const int kNumBuckets = 50; 286 const int kNumBuckets = 50;
183 287
184 if (isReliable()) { 288 if (channel()->reliable()) {
185 UMA_HISTOGRAM_CUSTOM_COUNTS("WebRTC.ReliableDataChannelMessageSize", 289 UMA_HISTOGRAM_CUSTOM_COUNTS("WebRTC.ReliableDataChannelMessageSize",
186 num_bytes, 290 num_bytes,
187 1, kMaxBucketSize, kNumBuckets); 291 1, kMaxBucketSize, kNumBuckets);
188 } else { 292 } else {
189 UMA_HISTOGRAM_CUSTOM_COUNTS("WebRTC.UnreliableDataChannelMessageSize", 293 UMA_HISTOGRAM_CUSTOM_COUNTS("WebRTC.UnreliableDataChannelMessageSize",
190 num_bytes, 294 num_bytes,
191 1, kMaxBucketSize, kNumBuckets); 295 1, kMaxBucketSize, kNumBuckets);
192 } 296 }
193 } 297 }
194 298
195 } // namespace content 299 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/rtc_data_channel_handler.h ('k') | content/renderer/media/rtc_peer_connection_handler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698