| 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 "content/browser/devtools/protocol/tethering_handler.h" | 5 #include "content/browser/devtools/protocol/tethering_handler.h" |
| 6 | 6 |
| 7 #include <map> |
| 8 |
| 7 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 8 #include "content/public/browser/browser_thread.h" | 10 #include "content/public/browser/browser_thread.h" |
| 9 #include "net/base/io_buffer.h" | 11 #include "net/base/io_buffer.h" |
| 10 #include "net/base/ip_address.h" | 12 #include "net/base/ip_address.h" |
| 11 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
| 12 #include "net/log/net_log_source.h" | 14 #include "net/log/net_log_source.h" |
| 13 #include "net/socket/server_socket.h" | 15 #include "net/socket/server_socket.h" |
| 14 #include "net/socket/stream_socket.h" | 16 #include "net/socket/stream_socket.h" |
| 15 #include "net/socket/tcp_server_socket.h" | 17 #include "net/socket/tcp_server_socket.h" |
| 16 | 18 |
| 17 namespace content { | 19 namespace content { |
| 18 namespace devtools { | 20 namespace protocol { |
| 19 namespace tethering { | 21 |
| 22 using BindCallback = Tethering::Backend::BindCallback; |
| 23 using UnbindCallback = Tethering::Backend::UnbindCallback; |
| 20 | 24 |
| 21 namespace { | 25 namespace { |
| 22 | 26 |
| 23 const int kListenBacklog = 5; | 27 const int kListenBacklog = 5; |
| 24 const int kBufferSize = 16 * 1024; | 28 const int kBufferSize = 16 * 1024; |
| 25 | 29 |
| 26 const int kMinTetheringPort = 1024; | 30 const int kMinTetheringPort = 1024; |
| 27 const int kMaxTetheringPort = 32767; | 31 const int kMaxTetheringPort = 32767; |
| 28 | 32 |
| 29 using Response = DevToolsProtocolClient::Response; | |
| 30 using CreateServerSocketCallback = | 33 using CreateServerSocketCallback = |
| 31 base::Callback<std::unique_ptr<net::ServerSocket>(std::string*)>; | 34 base::Callback<std::unique_ptr<net::ServerSocket>(std::string*)>; |
| 32 | 35 |
| 33 class SocketPump { | 36 class SocketPump { |
| 34 public: | 37 public: |
| 35 SocketPump(net::StreamSocket* client_socket) | 38 SocketPump(net::StreamSocket* client_socket) |
| 36 : client_socket_(client_socket), | 39 : client_socket_(client_socket), |
| 37 pending_writes_(0), | 40 pending_writes_(0), |
| 38 pending_destruction_(false) { | 41 pending_destruction_(false) { |
| 39 } | 42 } |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 | 232 |
| 230 // TetheringHandler::TetheringImpl ------------------------------------------- | 233 // TetheringHandler::TetheringImpl ------------------------------------------- |
| 231 | 234 |
| 232 class TetheringHandler::TetheringImpl { | 235 class TetheringHandler::TetheringImpl { |
| 233 public: | 236 public: |
| 234 TetheringImpl( | 237 TetheringImpl( |
| 235 base::WeakPtr<TetheringHandler> handler, | 238 base::WeakPtr<TetheringHandler> handler, |
| 236 const CreateServerSocketCallback& socket_callback); | 239 const CreateServerSocketCallback& socket_callback); |
| 237 ~TetheringImpl(); | 240 ~TetheringImpl(); |
| 238 | 241 |
| 239 void Bind(DevToolsCommandId command_id, uint16_t port); | 242 void Bind(uint16_t port, std::unique_ptr<BindCallback> callback); |
| 240 void Unbind(DevToolsCommandId command_id, uint16_t port); | 243 void Unbind(uint16_t port, std::unique_ptr<UnbindCallback> callback); |
| 241 void Accepted(uint16_t port, const std::string& name); | 244 void Accepted(uint16_t port, const std::string& name); |
| 242 | 245 |
| 243 private: | 246 private: |
| 244 void SendInternalError(DevToolsCommandId command_id, | |
| 245 const std::string& message); | |
| 246 | |
| 247 base::WeakPtr<TetheringHandler> handler_; | 247 base::WeakPtr<TetheringHandler> handler_; |
| 248 CreateServerSocketCallback socket_callback_; | 248 CreateServerSocketCallback socket_callback_; |
| 249 | |
| 250 std::map<uint16_t, std::unique_ptr<BoundSocket>> bound_sockets_; | 249 std::map<uint16_t, std::unique_ptr<BoundSocket>> bound_sockets_; |
| 251 }; | 250 }; |
| 252 | 251 |
| 253 TetheringHandler::TetheringImpl::TetheringImpl( | 252 TetheringHandler::TetheringImpl::TetheringImpl( |
| 254 base::WeakPtr<TetheringHandler> handler, | 253 base::WeakPtr<TetheringHandler> handler, |
| 255 const CreateServerSocketCallback& socket_callback) | 254 const CreateServerSocketCallback& socket_callback) |
| 256 : handler_(handler), | 255 : handler_(handler), |
| 257 socket_callback_(socket_callback) { | 256 socket_callback_(socket_callback) { |
| 258 } | 257 } |
| 259 | 258 |
| 260 TetheringHandler::TetheringImpl::~TetheringImpl() = default; | 259 TetheringHandler::TetheringImpl::~TetheringImpl() = default; |
| 261 | 260 |
| 262 void TetheringHandler::TetheringImpl::Bind(DevToolsCommandId command_id, | 261 void TetheringHandler::TetheringImpl::Bind( |
| 263 uint16_t port) { | 262 uint16_t port, std::unique_ptr<BindCallback> callback) { |
| 264 if (bound_sockets_.find(port) != bound_sockets_.end()) { | 263 if (bound_sockets_.find(port) != bound_sockets_.end()) { |
| 265 SendInternalError(command_id, "Port already bound"); | 264 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( |
| 265 &BindCallback::sendFailure, |
| 266 base::Passed(std::move(callback)), |
| 267 Response::Error("Port already bound"))); |
| 266 return; | 268 return; |
| 267 } | 269 } |
| 268 | 270 |
| 269 BoundSocket::AcceptedCallback callback = base::Bind( | 271 BoundSocket::AcceptedCallback accepted = base::Bind( |
| 270 &TetheringHandler::TetheringImpl::Accepted, base::Unretained(this)); | 272 &TetheringHandler::TetheringImpl::Accepted, base::Unretained(this)); |
| 271 std::unique_ptr<BoundSocket> bound_socket = | 273 std::unique_ptr<BoundSocket> bound_socket = |
| 272 base::MakeUnique<BoundSocket>(callback, socket_callback_); | 274 base::MakeUnique<BoundSocket>(accepted, socket_callback_); |
| 273 if (!bound_socket->Listen(port)) { | 275 if (!bound_socket->Listen(port)) { |
| 274 SendInternalError(command_id, "Could not bind port"); | 276 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( |
| 277 &BindCallback::sendFailure, |
| 278 base::Passed(std::move(callback)), |
| 279 Response::Error("Could not bind port"))); |
| 275 return; | 280 return; |
| 276 } | 281 } |
| 277 | 282 |
| 278 bound_sockets_[port] = std::move(bound_socket); | 283 bound_sockets_[port] = std::move(bound_socket); |
| 279 BrowserThread::PostTask( | 284 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( |
| 280 BrowserThread::UI, | 285 &BindCallback::sendSuccess, |
| 281 FROM_HERE, | 286 base::Passed(std::move(callback)))); |
| 282 base::Bind(&TetheringHandler::SendBindSuccess, handler_, command_id)); | |
| 283 } | 287 } |
| 284 | 288 |
| 285 void TetheringHandler::TetheringImpl::Unbind(DevToolsCommandId command_id, | 289 void TetheringHandler::TetheringImpl::Unbind( |
| 286 uint16_t port) { | 290 uint16_t port, std::unique_ptr<UnbindCallback> callback) { |
| 287 auto it = bound_sockets_.find(port); | 291 auto it = bound_sockets_.find(port); |
| 288 if (it == bound_sockets_.end()) { | 292 if (it == bound_sockets_.end()) { |
| 289 SendInternalError(command_id, "Port is not bound"); | 293 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( |
| 294 &UnbindCallback::sendFailure, |
| 295 base::Passed(std::move(callback)), |
| 296 Response::InvalidParams("Port is not bound"))); |
| 290 return; | 297 return; |
| 291 } | 298 } |
| 292 | 299 |
| 293 bound_sockets_.erase(it); | 300 bound_sockets_.erase(it); |
| 294 BrowserThread::PostTask( | 301 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( |
| 295 BrowserThread::UI, | 302 &UnbindCallback::sendSuccess, |
| 296 FROM_HERE, | 303 base::Passed(std::move(callback)))); |
| 297 base::Bind(&TetheringHandler::SendUnbindSuccess, handler_, command_id)); | |
| 298 } | 304 } |
| 299 | 305 |
| 300 void TetheringHandler::TetheringImpl::Accepted(uint16_t port, | 306 void TetheringHandler::TetheringImpl::Accepted(uint16_t port, |
| 301 const std::string& name) { | 307 const std::string& name) { |
| 302 BrowserThread::PostTask( | 308 BrowserThread::PostTask( |
| 303 BrowserThread::UI, | 309 BrowserThread::UI, |
| 304 FROM_HERE, | 310 FROM_HERE, |
| 305 base::Bind(&TetheringHandler::Accepted, handler_, port, name)); | 311 base::Bind(&TetheringHandler::Accepted, handler_, port, name)); |
| 306 } | 312 } |
| 307 | 313 |
| 308 void TetheringHandler::TetheringImpl::SendInternalError( | |
| 309 DevToolsCommandId command_id, | |
| 310 const std::string& message) { | |
| 311 BrowserThread::PostTask( | |
| 312 BrowserThread::UI, | |
| 313 FROM_HERE, | |
| 314 base::Bind(&TetheringHandler::SendInternalError, handler_, | |
| 315 command_id, message)); | |
| 316 } | |
| 317 | |
| 318 | 314 |
| 319 // TetheringHandler ---------------------------------------------------------- | 315 // TetheringHandler ---------------------------------------------------------- |
| 320 | 316 |
| 321 // static | 317 // static |
| 322 TetheringHandler::TetheringImpl* TetheringHandler::impl_ = nullptr; | 318 TetheringHandler::TetheringImpl* TetheringHandler::impl_ = nullptr; |
| 323 | 319 |
| 324 TetheringHandler::TetheringHandler( | 320 TetheringHandler::TetheringHandler( |
| 325 const CreateServerSocketCallback& socket_callback, | 321 const CreateServerSocketCallback& socket_callback, |
| 326 scoped_refptr<base::SingleThreadTaskRunner> task_runner) | 322 scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
| 327 : socket_callback_(socket_callback), | 323 : socket_callback_(socket_callback), |
| 328 task_runner_(task_runner), | 324 task_runner_(task_runner), |
| 329 is_active_(false), | 325 is_active_(false), |
| 330 weak_factory_(this) { | 326 weak_factory_(this) { |
| 331 } | 327 } |
| 332 | 328 |
| 333 TetheringHandler::~TetheringHandler() { | 329 TetheringHandler::~TetheringHandler() { |
| 334 if (is_active_) { | 330 if (is_active_) { |
| 335 task_runner_->DeleteSoon(FROM_HERE, impl_); | 331 task_runner_->DeleteSoon(FROM_HERE, impl_); |
| 336 impl_ = nullptr; | 332 impl_ = nullptr; |
| 337 } | 333 } |
| 338 } | 334 } |
| 339 | 335 |
| 340 void TetheringHandler::SetClient(std::unique_ptr<Client> client) { | 336 void TetheringHandler::Wire(UberDispatcher* dispatcher) { |
| 341 client_.swap(client); | 337 frontend_.reset(new Tethering::Frontend(dispatcher->channel())); |
| 338 Tethering::Dispatcher::wire(dispatcher, this); |
| 339 } |
| 340 |
| 341 Response TetheringHandler::Disable() { |
| 342 return Response::OK(); |
| 342 } | 343 } |
| 343 | 344 |
| 344 void TetheringHandler::Accepted(uint16_t port, const std::string& name) { | 345 void TetheringHandler::Accepted(uint16_t port, const std::string& name) { |
| 345 client_->Accepted(AcceptedParams::Create()->set_port(port) | 346 frontend_->Accepted(port, name); |
| 346 ->set_connection_id(name)); | |
| 347 } | 347 } |
| 348 | 348 |
| 349 bool TetheringHandler::Activate() { | 349 bool TetheringHandler::Activate() { |
| 350 if (is_active_) | 350 if (is_active_) |
| 351 return true; | 351 return true; |
| 352 if (impl_) | 352 if (impl_) |
| 353 return false; | 353 return false; |
| 354 is_active_ = true; | 354 is_active_ = true; |
| 355 impl_ = new TetheringImpl(weak_factory_.GetWeakPtr(), socket_callback_); | 355 impl_ = new TetheringImpl(weak_factory_.GetWeakPtr(), socket_callback_); |
| 356 return true; | 356 return true; |
| 357 } | 357 } |
| 358 | 358 |
| 359 Response TetheringHandler::Bind(DevToolsCommandId command_id, int port) { | 359 void TetheringHandler::Bind( |
| 360 if (port < kMinTetheringPort || port > kMaxTetheringPort) | 360 int port, std::unique_ptr<BindCallback> callback) { |
| 361 return Response::InvalidParams("port"); | 361 if (port < kMinTetheringPort || port > kMaxTetheringPort) { |
| 362 callback->sendFailure(Response::InvalidParams("port")); |
| 363 return; |
| 364 } |
| 362 | 365 |
| 363 if (!Activate()) | 366 if (!Activate()) { |
| 364 return Response::ServerError("Tethering is used by another connection"); | 367 callback->sendFailure( |
| 368 Response::Error("Tethering is used by another connection")); |
| 369 return; |
| 370 } |
| 365 | 371 |
| 366 DCHECK(impl_); | 372 DCHECK(impl_); |
| 367 task_runner_->PostTask( | 373 task_runner_->PostTask( |
| 368 FROM_HERE, base::Bind(&TetheringImpl::Bind, base::Unretained(impl_), | 374 FROM_HERE, base::Bind(&TetheringImpl::Bind, base::Unretained(impl_), |
| 369 command_id, port)); | 375 port, base::Passed(std::move(callback)))); |
| 370 return Response::OK(); | |
| 371 } | 376 } |
| 372 | 377 |
| 373 Response TetheringHandler::Unbind(DevToolsCommandId command_id, int port) { | 378 void TetheringHandler::Unbind( |
| 374 if (!Activate()) | 379 int port, std::unique_ptr<UnbindCallback> callback) { |
| 375 return Response::ServerError("Tethering is used by another connection"); | 380 if (!Activate()) { |
| 381 callback->sendFailure( |
| 382 Response::Error("Tethering is used by another connection")); |
| 383 return; |
| 384 } |
| 376 | 385 |
| 377 DCHECK(impl_); | 386 DCHECK(impl_); |
| 378 task_runner_->PostTask( | 387 task_runner_->PostTask( |
| 379 FROM_HERE, base::Bind(&TetheringImpl::Unbind, base::Unretained(impl_), | 388 FROM_HERE, base::Bind(&TetheringImpl::Unbind, base::Unretained(impl_), |
| 380 command_id, port)); | 389 port, base::Passed(std::move(callback)))); |
| 381 return Response::OK(); | |
| 382 } | 390 } |
| 383 | 391 |
| 384 void TetheringHandler::SendBindSuccess(DevToolsCommandId command_id) { | 392 } // namespace protocol |
| 385 client_->SendBindResponse(command_id, BindResponse::Create()); | |
| 386 } | |
| 387 | |
| 388 void TetheringHandler::SendUnbindSuccess(DevToolsCommandId command_id) { | |
| 389 client_->SendUnbindResponse(command_id, UnbindResponse::Create()); | |
| 390 } | |
| 391 | |
| 392 void TetheringHandler::SendInternalError(DevToolsCommandId command_id, | |
| 393 const std::string& message) { | |
| 394 client_->SendError(command_id, Response::InternalError(message)); | |
| 395 } | |
| 396 | |
| 397 } // namespace tethering | |
| 398 } // namespace devtools | |
| 399 } // namespace content | 393 } // namespace content |
| OLD | NEW |