Home | History | Annotate | Download | only in forwarder2
      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 "tools/android/forwarder2/device_listener.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/callback.h"
     10 #include "base/logging.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/message_loop/message_loop_proxy.h"
     13 #include "base/single_thread_task_runner.h"
     14 #include "tools/android/forwarder2/command.h"
     15 #include "tools/android/forwarder2/forwarder.h"
     16 #include "tools/android/forwarder2/socket.h"
     17 
     18 namespace forwarder2 {
     19 
     20 // static
     21 scoped_ptr<DeviceListener> DeviceListener::Create(
     22     scoped_ptr<Socket> host_socket,
     23     int listener_port,
     24     const DeleteCallback& delete_callback) {
     25   scoped_ptr<Socket> listener_socket(new Socket());
     26   scoped_ptr<DeviceListener> device_listener;
     27   if (!listener_socket->BindTcp("", listener_port)) {
     28     LOG(ERROR) << "Device could not bind and listen to local port "
     29                << listener_port;
     30     SendCommand(command::BIND_ERROR, listener_port, host_socket.get());
     31     return device_listener.Pass();
     32   }
     33   // In case the |listener_port_| was zero, GetPort() will return the
     34   // currently (non-zero) allocated port for this socket.
     35   listener_port = listener_socket->GetPort();
     36   SendCommand(command::BIND_SUCCESS, listener_port, host_socket.get());
     37   device_listener.reset(
     38       new DeviceListener(
     39           scoped_ptr<PipeNotifier>(new PipeNotifier()), listener_socket.Pass(),
     40           host_socket.Pass(), listener_port, delete_callback));
     41   return device_listener.Pass();
     42 }
     43 
     44 DeviceListener::~DeviceListener() {
     45   DCHECK(deletion_task_runner_->RunsTasksOnCurrentThread());
     46   exit_notifier_->Notify();
     47 }
     48 
     49 void DeviceListener::Start() {
     50   thread_.Start();
     51   AcceptNextClientSoon();
     52 }
     53 
     54 void DeviceListener::SetAdbDataSocket(scoped_ptr<Socket> adb_data_socket) {
     55   thread_.message_loop_proxy()->PostTask(
     56       FROM_HERE,
     57       base::Bind(&DeviceListener::OnAdbDataSocketReceivedOnInternalThread,
     58                  base::Unretained(this), base::Passed(&adb_data_socket)));
     59 }
     60 
     61 DeviceListener::DeviceListener(scoped_ptr<PipeNotifier> pipe_notifier,
     62                                scoped_ptr<Socket> listener_socket,
     63                                scoped_ptr<Socket> host_socket,
     64                                int port,
     65                                const DeleteCallback& delete_callback)
     66     : exit_notifier_(pipe_notifier.Pass()),
     67       listener_socket_(listener_socket.Pass()),
     68       host_socket_(host_socket.Pass()),
     69       listener_port_(port),
     70       delete_callback_(delete_callback),
     71       deletion_task_runner_(base::MessageLoopProxy::current()),
     72       thread_("DeviceListener") {
     73   CHECK(host_socket_.get());
     74   DCHECK(deletion_task_runner_.get());
     75   DCHECK(exit_notifier_.get());
     76   host_socket_->AddEventFd(exit_notifier_->receiver_fd());
     77   listener_socket_->AddEventFd(exit_notifier_->receiver_fd());
     78 }
     79 
     80 void DeviceListener::AcceptNextClientSoon() {
     81   thread_.message_loop_proxy()->PostTask(
     82       FROM_HERE,
     83       base::Bind(&DeviceListener::AcceptClientOnInternalThread,
     84                  base::Unretained(this)));
     85 }
     86 
     87 void DeviceListener::AcceptClientOnInternalThread() {
     88   device_data_socket_.reset(new Socket());
     89   if (!listener_socket_->Accept(device_data_socket_.get())) {
     90     if (listener_socket_->DidReceiveEvent()) {
     91       LOG(INFO) << "Received exit notification, stopped accepting clients.";
     92       SelfDelete();
     93       return;
     94     }
     95     LOG(WARNING) << "Could not Accept in ListenerSocket.";
     96     SendCommand(command::ACCEPT_ERROR, listener_port_, host_socket_.get());
     97     SelfDelete();
     98     return;
     99   }
    100   SendCommand(command::ACCEPT_SUCCESS, listener_port_, host_socket_.get());
    101   if (!ReceivedCommand(command::HOST_SERVER_SUCCESS,
    102                        host_socket_.get())) {
    103     SendCommand(command::ACK, listener_port_, host_socket_.get());
    104     LOG(ERROR) << "Host could not connect to server.";
    105     device_data_socket_->Close();
    106     if (host_socket_->has_error()) {
    107       LOG(ERROR) << "Adb Control connection lost. "
    108                  << "Listener port: " << listener_port_;
    109       SelfDelete();
    110       return;
    111     }
    112     // It can continue if the host forwarder could not connect to the host
    113     // server but the control connection is still alive (no errors). The device
    114     // acknowledged that (above), and it can re-try later.
    115     AcceptNextClientSoon();
    116     return;
    117   }
    118 }
    119 
    120 void DeviceListener::OnAdbDataSocketReceivedOnInternalThread(
    121     scoped_ptr<Socket> adb_data_socket) {
    122   adb_data_socket_.swap(adb_data_socket);
    123   SendCommand(command::ADB_DATA_SOCKET_SUCCESS, listener_port_,
    124               host_socket_.get());
    125   CHECK(adb_data_socket_.get());
    126   StartForwarder(device_data_socket_.Pass(), adb_data_socket_.Pass());
    127   AcceptNextClientSoon();
    128 }
    129 
    130 void DeviceListener::SelfDelete() {
    131   if (!deletion_task_runner_->RunsTasksOnCurrentThread()) {
    132     deletion_task_runner_->PostTask(
    133         FROM_HERE,
    134         base::Bind(&DeviceListener::SelfDeleteOnDeletionTaskRunner,
    135                    delete_callback_, listener_port_));
    136     return;
    137   }
    138   SelfDeleteOnDeletionTaskRunner(delete_callback_, listener_port_);
    139 }
    140 
    141 // static
    142 void DeviceListener::SelfDeleteOnDeletionTaskRunner(
    143     const DeleteCallback& delete_callback,
    144     int listener_port) {
    145   delete_callback.Run(listener_port);
    146 }
    147 
    148 }  // namespace forwarder
    149