15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tools/android/forwarder2/host_controller.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/bind.h" 10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/bind_helpers.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tools/android/forwarder2/command.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tools/android/forwarder2/forwarder.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tools/android/forwarder2/socket.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace forwarder2 { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// static 20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochscoped_ptr<HostController> HostController::Create( 21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch int device_port, 22d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch int host_port, 23d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch int adb_port, 24d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch int exit_notifier_fd, 25d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const DeletionCallback& deletion_callback) { 26d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scoped_ptr<HostController> host_controller; 27d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scoped_ptr<PipeNotifier> delete_controller_notifier(new PipeNotifier()); 28d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scoped_ptr<Socket> adb_control_socket(new Socket()); 29d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch adb_control_socket->AddEventFd(exit_notifier_fd); 30d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch adb_control_socket->AddEventFd(delete_controller_notifier->receiver_fd()); 31d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!adb_control_socket->ConnectTcp(std::string(), adb_port)) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Could not connect HostController socket on port: " 33d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch << adb_port; 34d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return host_controller.Pass(); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send the command to the device start listening to the "device_forward_port" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool send_command_success = SendCommand( 38d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch command::LISTEN, device_port, adb_control_socket.get()); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(send_command_success); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int device_port_allocated; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command::Type command; 42d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!ReadCommand( 43d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch adb_control_socket.get(), &device_port_allocated, &command) || 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command != command::BIND_SUCCESS) { 45d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch LOG(ERROR) << "Device binding error using port " << device_port; 46d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return host_controller.Pass(); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch host_controller.reset( 49d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch new HostController( 50d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch device_port_allocated, host_port, adb_port, exit_notifier_fd, 51d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch deletion_callback, adb_control_socket.Pass(), 52d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch delete_controller_notifier.Pass())); 53d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return host_controller.Pass(); 54d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 55d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 56d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochHostController::~HostController() { 57d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch DCHECK(deletion_task_runner_->RunsTasksOnCurrentThread()); 58d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch delete_controller_notifier_->Notify(); 59d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Note that the Forwarder instance (that also received a delete notification) 60d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // might still be running on its own thread at this point. This is not a 61d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // problem since it will self-delete once the socket that it is operating on 62d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // is closed. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HostController::Start() { 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch thread_.Start(); 67d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ReadNextCommandSoon(); 68d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 69d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 70d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochHostController::HostController( 71d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch int device_port, 72d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch int host_port, 73d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch int adb_port, 74d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch int exit_notifier_fd, 75d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const DeletionCallback& deletion_callback, 76d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scoped_ptr<Socket> adb_control_socket, 77d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scoped_ptr<PipeNotifier> delete_controller_notifier) 78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch : device_port_(device_port), 79d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch host_port_(host_port), 80d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch adb_port_(adb_port), 81d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch global_exit_notifier_fd_(exit_notifier_fd), 82d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch deletion_callback_(deletion_callback), 83d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch adb_control_socket_(adb_control_socket.Pass()), 84d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch delete_controller_notifier_(delete_controller_notifier.Pass()), 85d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch deletion_task_runner_(base::MessageLoopProxy::current()), 86d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch thread_("HostControllerThread") { 87d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 88d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 89d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid HostController::ReadNextCommandSoon() { 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch thread_.message_loop_proxy()->PostTask( 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FROM_HERE, 92d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::Bind(&HostController::ReadCommandOnInternalThread, 93d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::Unretained(this))); 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 96d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid HostController::ReadCommandOnInternalThread() { 97d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!ReceivedCommand(command::ACCEPT_SUCCESS, adb_control_socket_.get())) { 98d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch SelfDelete(); 99d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return; 100d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 101d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Try to connect to host server. 102d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scoped_ptr<Socket> host_server_data_socket(CreateSocket()); 103d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!host_server_data_socket->ConnectTcp(std::string(), host_port_)) { 104d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch LOG(ERROR) << "Could not Connect HostServerData socket on port: " 105d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch << host_port_; 106d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch SendCommand( 107d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch command::HOST_SERVER_ERROR, device_port_, adb_control_socket_.get()); 108d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (ReceivedCommand(command::ACK, adb_control_socket_.get())) { 109d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // It can continue if the host forwarder could not connect to the host 110d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // server but the device acknowledged that, so that the device could 111d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // re-try later. 112d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ReadNextCommandSoon(); 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 115d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch SelfDelete(); 116d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 118d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch SendCommand( 119d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch command::HOST_SERVER_SUCCESS, device_port_, adb_control_socket_.get()); 120d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch StartForwarder(host_server_data_socket.Pass()); 121d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ReadNextCommandSoon(); 1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HostController::StartForwarder( 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<Socket> host_server_data_socket) { 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<Socket> adb_data_socket(CreateSocket()); 1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!adb_data_socket->ConnectTcp("", adb_port_)) { 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LOG(ERROR) << "Could not connect AdbDataSocket on port: " << adb_port_; 129ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SelfDelete(); 1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Open the Adb data connection, and send a command with the 1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // |device_forward_port| as a way for the device to identify the connection. 134d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch SendCommand(command::DATA_CONNECTION, device_port_, adb_data_socket.get()); 1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Check that the device received the new Adb Data Connection. Note that this 1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // check is done through the |adb_control_socket_| that is handled in the 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // DeviceListener thread just after the call to WaitForAdbDataSocket(). 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!ReceivedCommand(command::ADB_DATA_SOCKET_SUCCESS, 140d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch adb_control_socket_.get())) { 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LOG(ERROR) << "Device could not handle the new Adb Data Connection."; 142ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SelfDelete(); 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 145d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch forwarder2::StartForwarder( 146d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch host_server_data_socket.Pass(), adb_data_socket.Pass()); 1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochscoped_ptr<Socket> HostController::CreateSocket() { 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<Socket> socket(new Socket()); 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch socket->AddEventFd(global_exit_notifier_fd_); 152d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch socket->AddEventFd(delete_controller_notifier_->receiver_fd()); 1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return socket.Pass(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 156ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid HostController::SelfDelete() { 157d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scoped_ptr<HostController> self_deleter(this); 158d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch deletion_task_runner_->PostTask( 159d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch FROM_HERE, 160d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::Bind(&HostController::SelfDeleteOnDeletionTaskRunner, 161d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch deletion_callback_, base::Passed(&self_deleter))); 162ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Tell the device to delete its corresponding controller instance before we 163ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // self-delete. 164ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Socket socket; 165ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!socket.ConnectTcp("", adb_port_)) { 166ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch LOG(ERROR) << "Could not connect to device on port " << adb_port_; 167ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 168ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 169d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!SendCommand(command::UNLISTEN, device_port_, &socket)) { 170ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch LOG(ERROR) << "Could not send unmap command for port " << device_port_; 171ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 172ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 173d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!ReceivedCommand(command::UNLISTEN_SUCCESS, &socket)) { 174ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch LOG(ERROR) << "Unamp command failed for port " << device_port_; 175ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 176ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 177ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 178ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 179d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// static 180d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid HostController::SelfDeleteOnDeletionTaskRunner( 181d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const DeletionCallback& deletion_callback, 182d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scoped_ptr<HostController> controller) { 183d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch deletion_callback.Run(controller.Pass()); 184d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 185d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace forwarder2 187