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/p2p/host_address_request.h" 6 7 #include "base/bind.h" 8 #include "base/message_loop/message_loop_proxy.h" 9 #include "content/common/p2p_messages.h" 10 #include "content/renderer/p2p/socket_dispatcher.h" 11 12 namespace content { 13 14 P2PHostAddressRequest::P2PHostAddressRequest(P2PSocketDispatcher* dispatcher) 15 : dispatcher_(dispatcher), 16 ipc_message_loop_(dispatcher->message_loop()), 17 delegate_message_loop_(base::MessageLoopProxy::current()), 18 state_(STATE_CREATED), 19 request_id_(0), 20 registered_(false) { 21 } 22 23 P2PHostAddressRequest::~P2PHostAddressRequest() { 24 DCHECK(state_ == STATE_CREATED || state_ == STATE_FINISHED); 25 DCHECK(!registered_); 26 } 27 28 void P2PHostAddressRequest::Request(const std::string& host_name, 29 const DoneCallback& done_callback) { 30 DCHECK(delegate_message_loop_->BelongsToCurrentThread()); 31 DCHECK_EQ(STATE_CREATED, state_); 32 33 state_ = STATE_SENT; 34 ipc_message_loop_->PostTask(FROM_HERE, base::Bind( 35 &P2PHostAddressRequest::DoSendRequest, this, host_name, done_callback)); 36 } 37 38 void P2PHostAddressRequest::Cancel() { 39 DCHECK(delegate_message_loop_->BelongsToCurrentThread()); 40 41 if (state_ != STATE_FINISHED) { 42 state_ = STATE_FINISHED; 43 ipc_message_loop_->PostTask(FROM_HERE, base::Bind( 44 &P2PHostAddressRequest::DoUnregister, this)); 45 } 46 } 47 48 void P2PHostAddressRequest::DoSendRequest(const std::string& host_name, 49 const DoneCallback& done_callback) { 50 DCHECK(ipc_message_loop_->BelongsToCurrentThread()); 51 52 done_callback_ = done_callback; 53 request_id_ = dispatcher_->RegisterHostAddressRequest(this); 54 registered_ = true; 55 dispatcher_->SendP2PMessage( 56 new P2PHostMsg_GetHostAddress(host_name, request_id_)); 57 } 58 59 void P2PHostAddressRequest::DoUnregister() { 60 DCHECK(ipc_message_loop_->BelongsToCurrentThread()); 61 if (registered_) { 62 dispatcher_->UnregisterHostAddressRequest(request_id_); 63 registered_ = false; 64 } 65 } 66 67 void P2PHostAddressRequest::OnResponse(const net::IPAddressNumber& address) { 68 DCHECK(ipc_message_loop_->BelongsToCurrentThread()); 69 DCHECK(registered_); 70 71 dispatcher_->UnregisterHostAddressRequest(request_id_); 72 registered_ = false; 73 74 delegate_message_loop_->PostTask(FROM_HERE, base::Bind( 75 &P2PHostAddressRequest::DeliverResponse, this, address)); 76 } 77 78 void P2PHostAddressRequest::DeliverResponse( 79 const net::IPAddressNumber& address) { 80 DCHECK(delegate_message_loop_->BelongsToCurrentThread()); 81 if (state_ == STATE_SENT) { 82 done_callback_.Run(address); 83 state_ = STATE_FINISHED; 84 } 85 } 86 87 } // namespace content 88