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