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