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 ErrorCallback& error_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(listener_socket.Pass(), host_socket.Pass(), 39 listener_port, error_callback)); 40 return device_listener.Pass(); 41 } 42 43 DeviceListener::~DeviceListener() { 44 DCHECK(deletion_task_runner_->RunsTasksOnCurrentThread()); 45 deletion_notifier_.Notify(); 46 } 47 48 void DeviceListener::Start() { 49 thread_.Start(); 50 AcceptNextClientSoon(); 51 } 52 53 void DeviceListener::SetAdbDataSocket(scoped_ptr<Socket> adb_data_socket) { 54 thread_.message_loop_proxy()->PostTask( 55 FROM_HERE, 56 base::Bind(&DeviceListener::OnAdbDataSocketReceivedOnInternalThread, 57 base::Unretained(this), base::Passed(&adb_data_socket))); 58 } 59 60 DeviceListener::DeviceListener(scoped_ptr<Socket> listener_socket, 61 scoped_ptr<Socket> host_socket, 62 int port, 63 const ErrorCallback& error_callback) 64 : self_deleter_helper_(this, error_callback), 65 listener_socket_(listener_socket.Pass()), 66 host_socket_(host_socket.Pass()), 67 listener_port_(port), 68 deletion_task_runner_(base::MessageLoopProxy::current()), 69 thread_("DeviceListener") { 70 CHECK(host_socket_.get()); 71 DCHECK(deletion_task_runner_.get()); 72 host_socket_->AddEventFd(deletion_notifier_.receiver_fd()); 73 listener_socket_->AddEventFd(deletion_notifier_.receiver_fd()); 74 } 75 76 void DeviceListener::AcceptNextClientSoon() { 77 thread_.message_loop_proxy()->PostTask( 78 FROM_HERE, 79 base::Bind(&DeviceListener::AcceptClientOnInternalThread, 80 base::Unretained(this))); 81 } 82 83 void DeviceListener::AcceptClientOnInternalThread() { 84 device_data_socket_.reset(new Socket()); 85 if (!listener_socket_->Accept(device_data_socket_.get())) { 86 if (listener_socket_->DidReceiveEvent()) { 87 LOG(INFO) << "Received exit notification, stopped accepting clients."; 88 OnInternalThreadError(); 89 return; 90 } 91 LOG(WARNING) << "Could not Accept in ListenerSocket."; 92 SendCommand(command::ACCEPT_ERROR, listener_port_, host_socket_.get()); 93 OnInternalThreadError(); 94 return; 95 } 96 SendCommand(command::ACCEPT_SUCCESS, listener_port_, host_socket_.get()); 97 if (!ReceivedCommand(command::HOST_SERVER_SUCCESS, 98 host_socket_.get())) { 99 SendCommand(command::ACK, listener_port_, host_socket_.get()); 100 LOG(ERROR) << "Host could not connect to server."; 101 device_data_socket_->Close(); 102 if (host_socket_->has_error()) { 103 LOG(ERROR) << "Adb Control connection lost. " 104 << "Listener port: " << listener_port_; 105 OnInternalThreadError(); 106 return; 107 } 108 // It can continue if the host forwarder could not connect to the host 109 // server but the control connection is still alive (no errors). The device 110 // acknowledged that (above), and it can re-try later. 111 AcceptNextClientSoon(); 112 return; 113 } 114 } 115 116 void DeviceListener::OnAdbDataSocketReceivedOnInternalThread( 117 scoped_ptr<Socket> adb_data_socket) { 118 DCHECK(adb_data_socket); 119 SendCommand(command::ADB_DATA_SOCKET_SUCCESS, listener_port_, 120 host_socket_.get()); 121 forwarders_manager_.CreateAndStartNewForwarder( 122 device_data_socket_.Pass(), adb_data_socket.Pass()); 123 AcceptNextClientSoon(); 124 } 125 126 void DeviceListener::OnInternalThreadError() { 127 self_deleter_helper_.MaybeSelfDeleteSoon(); 128 } 129 130 } // namespace forwarder 131