OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/browser/api/cast_channel/cast_transport.h" | 5 #include "components/cast_channel/cast_transport.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <string> | 10 #include <string> |
11 #include <utility> | 11 #include <utility> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/format_macros.h" | 14 #include "base/format_macros.h" |
15 #include "base/location.h" | 15 #include "base/location.h" |
16 #include "base/numerics/safe_conversions.h" | 16 #include "base/numerics/safe_conversions.h" |
17 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
18 #include "base/strings/stringprintf.h" | 18 #include "base/strings/stringprintf.h" |
19 #include "base/threading/thread_task_runner_handle.h" | 19 #include "base/threading/thread_task_runner_handle.h" |
20 #include "extensions/browser/api/cast_channel/cast_framer.h" | 20 #include "components/cast_channel/cast_framer.h" |
21 #include "extensions/browser/api/cast_channel/cast_message_util.h" | 21 #include "components/cast_channel/cast_message_util.h" |
22 #include "extensions/browser/api/cast_channel/logger.h" | 22 #include "components/cast_channel/logger.h" |
23 #include "extensions/common/api/cast_channel/cast_channel.pb.h" | 23 #include "components/cast_channel/proto/cast_channel.pb.h" |
24 #include "net/base/net_errors.h" | 24 #include "net/base/net_errors.h" |
25 #include "net/socket/socket.h" | 25 #include "net/socket/socket.h" |
26 | 26 |
27 #define VLOG_WITH_CONNECTION(level) \ | 27 #define VLOG_WITH_CONNECTION(level) \ |
28 VLOG(level) << "[" << ip_endpoint_.ToString() << ", auth=" \ | 28 VLOG(level) << "[" << ip_endpoint_.ToString() << ", auth=" \ |
29 << ::cast_channel::ChannelAuthTypeToString(channel_auth_) \ | 29 << ::cast_channel::ChannelAuthTypeToString(channel_auth_) \ |
30 << "] " | 30 << "] " |
31 | 31 |
32 namespace extensions { | |
33 namespace api { | |
34 namespace cast_channel { | 32 namespace cast_channel { |
35 | 33 |
36 CastTransportImpl::CastTransportImpl(net::Socket* socket, | 34 CastTransportImpl::CastTransportImpl(net::Socket* socket, |
37 int channel_id, | 35 int channel_id, |
38 const net::IPEndPoint& ip_endpoint, | 36 const net::IPEndPoint& ip_endpoint, |
39 ChannelAuthType channel_auth, | 37 ChannelAuthType channel_auth, |
40 scoped_refptr<Logger> logger) | 38 scoped_refptr<Logger> logger) |
41 : started_(false), | 39 : started_(false), |
42 socket_(socket), | 40 socket_(socket), |
43 write_state_(WRITE_STATE_IDLE), | 41 write_state_(WRITE_STATE_IDLE), |
44 read_state_(READ_STATE_READ), | 42 read_state_(READ_STATE_READ), |
45 error_state_(ChannelError::NONE), | 43 error_state_(ChannelError::NONE), |
46 channel_id_(channel_id), | 44 channel_id_(channel_id), |
47 ip_endpoint_(ip_endpoint), | 45 ip_endpoint_(ip_endpoint), |
48 channel_auth_(channel_auth), | 46 channel_auth_(channel_auth), |
49 logger_(logger) { | 47 logger_(logger) { |
50 DCHECK(socket); | 48 DCHECK(socket); |
51 | 49 |
52 // Buffer is reused across messages to minimize unnecessary buffer | 50 // Buffer is reused across messages to minimize unnecessary buffer |
53 // [re]allocations. | 51 // [re]allocations. |
54 read_buffer_ = new net::GrowableIOBuffer(); | 52 read_buffer_ = new net::GrowableIOBuffer(); |
55 read_buffer_->SetCapacity(MessageFramer::MessageHeader::max_message_size()); | 53 read_buffer_->SetCapacity(MessageFramer::MessageHeader::max_message_size()); |
56 framer_.reset(new MessageFramer(read_buffer_)); | 54 framer_.reset(new MessageFramer(read_buffer_)); |
57 } | 55 } |
58 | 56 |
59 CastTransportImpl::~CastTransportImpl() { | 57 CastTransportImpl::~CastTransportImpl() { |
60 DCHECK(CalledOnValidThread()); | 58 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
61 FlushWriteQueue(); | 59 FlushWriteQueue(); |
62 } | 60 } |
63 | 61 |
64 bool CastTransportImpl::IsTerminalWriteState( | 62 bool CastTransportImpl::IsTerminalWriteState( |
65 CastTransportImpl::WriteState write_state) { | 63 CastTransportImpl::WriteState write_state) { |
66 return write_state == WRITE_STATE_ERROR || write_state == WRITE_STATE_IDLE; | 64 return write_state == WRITE_STATE_ERROR || write_state == WRITE_STATE_IDLE; |
67 } | 65 } |
68 | 66 |
69 bool CastTransportImpl::IsTerminalReadState( | 67 bool CastTransportImpl::IsTerminalReadState( |
70 CastTransportImpl::ReadState read_state) { | 68 CastTransportImpl::ReadState read_state) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 return proto::CHANNEL_ERROR_CONNECT_TIMEOUT; | 138 return proto::CHANNEL_ERROR_CONNECT_TIMEOUT; |
141 case ChannelError::UNKNOWN: | 139 case ChannelError::UNKNOWN: |
142 return proto::CHANNEL_ERROR_UNKNOWN; | 140 return proto::CHANNEL_ERROR_UNKNOWN; |
143 default: | 141 default: |
144 NOTREACHED(); | 142 NOTREACHED(); |
145 return proto::CHANNEL_ERROR_NONE; | 143 return proto::CHANNEL_ERROR_NONE; |
146 } | 144 } |
147 } | 145 } |
148 | 146 |
149 void CastTransportImpl::SetReadDelegate(std::unique_ptr<Delegate> delegate) { | 147 void CastTransportImpl::SetReadDelegate(std::unique_ptr<Delegate> delegate) { |
150 DCHECK(CalledOnValidThread()); | 148 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
151 DCHECK(delegate); | 149 DCHECK(delegate); |
152 delegate_ = std::move(delegate); | 150 delegate_ = std::move(delegate); |
153 if (started_) { | 151 if (started_) { |
154 delegate_->Start(); | 152 delegate_->Start(); |
155 } | 153 } |
156 } | 154 } |
157 | 155 |
158 void CastTransportImpl::FlushWriteQueue() { | 156 void CastTransportImpl::FlushWriteQueue() { |
159 for (; !write_queue_.empty(); write_queue_.pop()) { | 157 for (; !write_queue_.empty(); write_queue_.pop()) { |
160 net::CompletionCallback& callback = write_queue_.front().callback; | 158 net::CompletionCallback& callback = write_queue_.front().callback; |
161 base::ThreadTaskRunnerHandle::Get()->PostTask( | 159 base::ThreadTaskRunnerHandle::Get()->PostTask( |
162 FROM_HERE, base::Bind(callback, net::ERR_FAILED)); | 160 FROM_HERE, base::Bind(callback, net::ERR_FAILED)); |
163 callback.Reset(); | 161 callback.Reset(); |
164 } | 162 } |
165 } | 163 } |
166 | 164 |
167 void CastTransportImpl::SendMessage(const CastMessage& message, | 165 void CastTransportImpl::SendMessage(const CastMessage& message, |
168 const net::CompletionCallback& callback) { | 166 const net::CompletionCallback& callback) { |
169 DCHECK(CalledOnValidThread()); | 167 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
170 std::string serialized_message; | 168 std::string serialized_message; |
171 if (!MessageFramer::Serialize(message, &serialized_message)) { | 169 if (!MessageFramer::Serialize(message, &serialized_message)) { |
172 base::ThreadTaskRunnerHandle::Get()->PostTask( | 170 base::ThreadTaskRunnerHandle::Get()->PostTask( |
173 FROM_HERE, base::Bind(callback, net::ERR_FAILED)); | 171 FROM_HERE, base::Bind(callback, net::ERR_FAILED)); |
174 return; | 172 return; |
175 } | 173 } |
176 WriteRequest write_request( | 174 WriteRequest write_request(message.namespace_(), serialized_message, |
177 message.namespace_(), serialized_message, callback); | 175 callback); |
178 | 176 |
179 write_queue_.push(write_request); | 177 write_queue_.push(write_request); |
180 if (write_state_ == WRITE_STATE_IDLE) { | 178 if (write_state_ == WRITE_STATE_IDLE) { |
181 SetWriteState(WRITE_STATE_WRITE); | 179 SetWriteState(WRITE_STATE_WRITE); |
182 OnWriteResult(net::OK); | 180 OnWriteResult(net::OK); |
183 } | 181 } |
184 } | 182 } |
185 | 183 |
186 CastTransportImpl::WriteRequest::WriteRequest( | 184 CastTransportImpl::WriteRequest::WriteRequest( |
187 const std::string& namespace_, | 185 const std::string& namespace_, |
188 const std::string& payload, | 186 const std::string& payload, |
189 const net::CompletionCallback& callback) | 187 const net::CompletionCallback& callback) |
190 : message_namespace(namespace_), callback(callback) { | 188 : message_namespace(namespace_), callback(callback) { |
191 VLOG(2) << "WriteRequest size: " << payload.size(); | 189 VLOG(2) << "WriteRequest size: " << payload.size(); |
192 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(payload), | 190 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(payload), |
193 payload.size()); | 191 payload.size()); |
194 } | 192 } |
195 | 193 |
196 CastTransportImpl::WriteRequest::WriteRequest(const WriteRequest& other) = | 194 CastTransportImpl::WriteRequest::WriteRequest(const WriteRequest& other) = |
197 default; | 195 default; |
198 | 196 |
199 CastTransportImpl::WriteRequest::~WriteRequest() { | 197 CastTransportImpl::WriteRequest::~WriteRequest() {} |
200 } | |
201 | 198 |
202 void CastTransportImpl::SetReadState(ReadState read_state) { | 199 void CastTransportImpl::SetReadState(ReadState read_state) { |
203 if (read_state_ != read_state) | 200 if (read_state_ != read_state) |
204 read_state_ = read_state; | 201 read_state_ = read_state; |
205 } | 202 } |
206 | 203 |
207 void CastTransportImpl::SetWriteState(WriteState write_state) { | 204 void CastTransportImpl::SetWriteState(WriteState write_state) { |
208 if (write_state_ != write_state) | 205 if (write_state_ != write_state) |
209 write_state_ = write_state; | 206 write_state_ = write_state; |
210 } | 207 } |
211 | 208 |
212 void CastTransportImpl::SetErrorState(ChannelError error_state) { | 209 void CastTransportImpl::SetErrorState(ChannelError error_state) { |
213 VLOG_WITH_CONNECTION(2) << "SetErrorState: " | 210 VLOG_WITH_CONNECTION(2) << "SetErrorState: " |
214 << ::cast_channel::ChannelErrorToString(error_state); | 211 << ::cast_channel::ChannelErrorToString(error_state); |
215 error_state_ = error_state; | 212 error_state_ = error_state; |
216 } | 213 } |
217 | 214 |
218 void CastTransportImpl::OnWriteResult(int result) { | 215 void CastTransportImpl::OnWriteResult(int result) { |
219 DCHECK(CalledOnValidThread()); | 216 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
220 DCHECK_NE(WRITE_STATE_IDLE, write_state_); | 217 DCHECK_NE(WRITE_STATE_IDLE, write_state_); |
221 if (write_queue_.empty()) { | 218 if (write_queue_.empty()) { |
222 SetWriteState(WRITE_STATE_IDLE); | 219 SetWriteState(WRITE_STATE_IDLE); |
223 return; | 220 return; |
224 } | 221 } |
225 | 222 |
226 // Network operations can either finish synchronously or asynchronously. | 223 // Network operations can either finish synchronously or asynchronously. |
227 // This method executes the state machine transitions in a loop so that | 224 // This method executes the state machine transitions in a loop so that |
228 // write state transitions happen even when network operations finish | 225 // write state transitions happen even when network operations finish |
229 // synchronously. | 226 // synchronously. |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 | 322 |
326 int CastTransportImpl::DoWriteHandleError(int result) { | 323 int CastTransportImpl::DoWriteHandleError(int result) { |
327 VLOG_WITH_CONNECTION(2) << "DoWriteHandleError result=" << result; | 324 VLOG_WITH_CONNECTION(2) << "DoWriteHandleError result=" << result; |
328 DCHECK_NE(ChannelError::NONE, error_state_); | 325 DCHECK_NE(ChannelError::NONE, error_state_); |
329 DCHECK_LT(result, 0); | 326 DCHECK_LT(result, 0); |
330 SetWriteState(WRITE_STATE_ERROR); | 327 SetWriteState(WRITE_STATE_ERROR); |
331 return net::ERR_FAILED; | 328 return net::ERR_FAILED; |
332 } | 329 } |
333 | 330 |
334 void CastTransportImpl::Start() { | 331 void CastTransportImpl::Start() { |
335 DCHECK(CalledOnValidThread()); | 332 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
336 DCHECK(!started_); | 333 DCHECK(!started_); |
337 DCHECK_EQ(READ_STATE_READ, read_state_); | 334 DCHECK_EQ(READ_STATE_READ, read_state_); |
338 DCHECK(delegate_) << "Read delegate must be set prior to calling Start()"; | 335 DCHECK(delegate_) << "Read delegate must be set prior to calling Start()"; |
339 started_ = true; | 336 started_ = true; |
340 delegate_->Start(); | 337 delegate_->Start(); |
341 SetReadState(READ_STATE_READ); | 338 SetReadState(READ_STATE_READ); |
342 | 339 |
343 // Start the read state machine. | 340 // Start the read state machine. |
344 OnReadResult(net::OK); | 341 OnReadResult(net::OK); |
345 } | 342 } |
346 | 343 |
347 void CastTransportImpl::OnReadResult(int result) { | 344 void CastTransportImpl::OnReadResult(int result) { |
348 DCHECK(CalledOnValidThread()); | 345 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
349 // Network operations can either finish synchronously or asynchronously. | 346 // Network operations can either finish synchronously or asynchronously. |
350 // This method executes the state machine transitions in a loop so that | 347 // This method executes the state machine transitions in a loop so that |
351 // write state transitions happen even when network operations finish | 348 // write state transitions happen even when network operations finish |
352 // synchronously. | 349 // synchronously. |
353 int rv = result; | 350 int rv = result; |
354 do { | 351 do { |
355 VLOG_WITH_CONNECTION(2) << "OnReadResult(state=" << read_state_ | 352 VLOG_WITH_CONNECTION(2) |
356 << ", result=" << rv << ")"; | 353 << "OnReadResult(state=" << read_state_ << ", result=" << rv << ")"; |
357 ReadState state = read_state_; | 354 ReadState state = read_state_; |
358 read_state_ = READ_STATE_UNKNOWN; | 355 read_state_ = READ_STATE_UNKNOWN; |
359 | 356 |
360 switch (state) { | 357 switch (state) { |
361 case READ_STATE_READ: | 358 case READ_STATE_READ: |
362 rv = DoRead(); | 359 rv = DoRead(); |
363 break; | 360 break; |
364 case READ_STATE_READ_COMPLETE: | 361 case READ_STATE_READ_COMPLETE: |
365 rv = DoReadComplete(rv); | 362 rv = DoReadComplete(rv); |
366 break; | 363 break; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 | 441 |
445 int CastTransportImpl::DoReadHandleError(int result) { | 442 int CastTransportImpl::DoReadHandleError(int result) { |
446 VLOG_WITH_CONNECTION(2) << "DoReadHandleError"; | 443 VLOG_WITH_CONNECTION(2) << "DoReadHandleError"; |
447 DCHECK_NE(ChannelError::NONE, error_state_); | 444 DCHECK_NE(ChannelError::NONE, error_state_); |
448 DCHECK_LE(result, 0); | 445 DCHECK_LE(result, 0); |
449 SetReadState(READ_STATE_ERROR); | 446 SetReadState(READ_STATE_ERROR); |
450 return net::ERR_FAILED; | 447 return net::ERR_FAILED; |
451 } | 448 } |
452 | 449 |
453 } // namespace cast_channel | 450 } // namespace cast_channel |
454 } // namespace api | |
455 } // namespace extensions | |
OLD | NEW |