| Index: tools/android/forwarder2/host_controller.cc
|
| diff --git a/tools/android/forwarder2/host_controller.cc b/tools/android/forwarder2/host_controller.cc
|
| index d98a4ad2e7c7cdc0a8c8ffc0177f6a449f37f163..1588e7291b2a65772f42c3fe54008e43dd3889fe 100644
|
| --- a/tools/android/forwarder2/host_controller.cc
|
| +++ b/tools/android/forwarder2/host_controller.cc
|
| @@ -16,95 +16,109 @@
|
|
|
| namespace forwarder2 {
|
|
|
| -HostController::HostController(int device_port,
|
| - const std::string& forward_to_host,
|
| - int forward_to_host_port,
|
| - int adb_port,
|
| - int exit_notifier_fd,
|
| - const DeleteCallback& delete_callback)
|
| - : device_port_(device_port),
|
| - forward_to_host_(forward_to_host),
|
| - forward_to_host_port_(forward_to_host_port),
|
| - adb_port_(adb_port),
|
| - global_exit_notifier_fd_(exit_notifier_fd),
|
| - delete_callback_(delete_callback),
|
| - ready_(false),
|
| - thread_("HostControllerThread") {
|
| - adb_control_socket_.AddEventFd(global_exit_notifier_fd_);
|
| - adb_control_socket_.AddEventFd(delete_controller_notifier_.receiver_fd());
|
| -}
|
| -
|
| -HostController::~HostController() {
|
| - delete_controller_notifier_.Notify();
|
| - // Note that the Forwarder instance (that also received a delete notification)
|
| - // might still be running on its own thread at this point. This is not a
|
| - // problem since it will self-delete once the socket that it is operating on
|
| - // is closed.
|
| -}
|
| -
|
| -bool HostController::Connect() {
|
| - if (!adb_control_socket_.ConnectTcp("", adb_port_)) {
|
| +// static
|
| +scoped_ptr<HostController> HostController::Create(
|
| + int device_port,
|
| + int host_port,
|
| + int adb_port,
|
| + int exit_notifier_fd,
|
| + const DeletionCallback& deletion_callback) {
|
| + scoped_ptr<HostController> host_controller;
|
| + scoped_ptr<PipeNotifier> delete_controller_notifier(new PipeNotifier());
|
| + scoped_ptr<Socket> adb_control_socket(new Socket());
|
| + adb_control_socket->AddEventFd(exit_notifier_fd);
|
| + adb_control_socket->AddEventFd(delete_controller_notifier->receiver_fd());
|
| + if (!adb_control_socket->ConnectTcp(std::string(), adb_port)) {
|
| LOG(ERROR) << "Could not connect HostController socket on port: "
|
| - << adb_port_;
|
| - SelfDelete();
|
| - return false;
|
| + << adb_port;
|
| + return host_controller.Pass();
|
| }
|
| // Send the command to the device start listening to the "device_forward_port"
|
| bool send_command_success = SendCommand(
|
| - command::LISTEN, device_port_, &adb_control_socket_);
|
| + command::LISTEN, device_port, adb_control_socket.get());
|
| CHECK(send_command_success);
|
| int device_port_allocated;
|
| command::Type command;
|
| - if (!ReadCommand(&adb_control_socket_, &device_port_allocated, &command) ||
|
| + if (!ReadCommand(
|
| + adb_control_socket.get(), &device_port_allocated, &command) ||
|
| command != command::BIND_SUCCESS) {
|
| - LOG(ERROR) << "Device binding error using port " << device_port_;
|
| - SelfDelete();
|
| - return false;
|
| + LOG(ERROR) << "Device binding error using port " << device_port;
|
| + return host_controller.Pass();
|
| }
|
| - // When doing dynamically allocation of port, we get the port from the
|
| - // BIND_SUCCESS command we received above.
|
| - device_port_ = device_port_allocated;
|
| - ready_ = true;
|
| - return true;
|
| + host_controller.reset(
|
| + new HostController(
|
| + device_port_allocated, host_port, adb_port, exit_notifier_fd,
|
| + deletion_callback, adb_control_socket.Pass(),
|
| + delete_controller_notifier.Pass()));
|
| + return host_controller.Pass();
|
| +}
|
| +
|
| +HostController::~HostController() {
|
| + DCHECK(deletion_task_runner_->RunsTasksOnCurrentThread());
|
| + delete_controller_notifier_->Notify();
|
| + // Note that the Forwarder instance (that also received a delete notification)
|
| + // might still be running on its own thread at this point. This is not a
|
| + // problem since it will self-delete once the socket that it is operating on
|
| + // is closed.
|
| }
|
|
|
| void HostController::Start() {
|
| thread_.Start();
|
| + ReadNextCommandSoon();
|
| +}
|
| +
|
| +HostController::HostController(
|
| + int device_port,
|
| + int host_port,
|
| + int adb_port,
|
| + int exit_notifier_fd,
|
| + const DeletionCallback& deletion_callback,
|
| + scoped_ptr<Socket> adb_control_socket,
|
| + scoped_ptr<PipeNotifier> delete_controller_notifier)
|
| + : device_port_(device_port),
|
| + host_port_(host_port),
|
| + adb_port_(adb_port),
|
| + global_exit_notifier_fd_(exit_notifier_fd),
|
| + deletion_callback_(deletion_callback),
|
| + adb_control_socket_(adb_control_socket.Pass()),
|
| + delete_controller_notifier_(delete_controller_notifier.Pass()),
|
| + deletion_task_runner_(base::MessageLoopProxy::current()),
|
| + thread_("HostControllerThread") {
|
| +}
|
| +
|
| +void HostController::ReadNextCommandSoon() {
|
| thread_.message_loop_proxy()->PostTask(
|
| FROM_HERE,
|
| - base::Bind(&HostController::ThreadHandler, base::Unretained(this)));
|
| + base::Bind(&HostController::ReadCommandOnInternalThread,
|
| + base::Unretained(this)));
|
| }
|
|
|
| -void HostController::ThreadHandler() {
|
| - CHECK(ready_) << "HostController not ready. Must call Connect() first.";
|
| - while (true) {
|
| - if (!ReceivedCommand(command::ACCEPT_SUCCESS, &adb_control_socket_)) {
|
| - SelfDelete();
|
| - return;
|
| - }
|
| - // Try to connect to host server.
|
| - scoped_ptr<Socket> host_server_data_socket(CreateSocket());
|
| - if (!host_server_data_socket->ConnectTcp(
|
| - forward_to_host_, forward_to_host_port_)) {
|
| - LOG(ERROR) << "Could not Connect HostServerData socket on port: "
|
| - << forward_to_host_port_;
|
| - SendCommand(command::HOST_SERVER_ERROR,
|
| - device_port_,
|
| - &adb_control_socket_);
|
| - if (ReceivedCommand(command::ACK, &adb_control_socket_)) {
|
| - // It can continue if the host forwarder could not connect to the host
|
| - // server but the device acknowledged that, so that the device could
|
| - // re-try later.
|
| - continue;
|
| - }
|
| - SelfDelete();
|
| +void HostController::ReadCommandOnInternalThread() {
|
| + if (!ReceivedCommand(command::ACCEPT_SUCCESS, adb_control_socket_.get())) {
|
| + SelfDelete();
|
| + return;
|
| + }
|
| + // Try to connect to host server.
|
| + scoped_ptr<Socket> host_server_data_socket(CreateSocket());
|
| + if (!host_server_data_socket->ConnectTcp(std::string(), host_port_)) {
|
| + LOG(ERROR) << "Could not Connect HostServerData socket on port: "
|
| + << host_port_;
|
| + SendCommand(
|
| + command::HOST_SERVER_ERROR, device_port_, adb_control_socket_.get());
|
| + if (ReceivedCommand(command::ACK, adb_control_socket_.get())) {
|
| + // It can continue if the host forwarder could not connect to the host
|
| + // server but the device acknowledged that, so that the device could
|
| + // re-try later.
|
| + ReadNextCommandSoon();
|
| return;
|
| }
|
| - SendCommand(command::HOST_SERVER_SUCCESS,
|
| - device_port_,
|
| - &adb_control_socket_);
|
| - StartForwarder(host_server_data_socket.Pass());
|
| + SelfDelete();
|
| + return;
|
| }
|
| + SendCommand(
|
| + command::HOST_SERVER_SUCCESS, device_port_, adb_control_socket_.get());
|
| + StartForwarder(host_server_data_socket.Pass());
|
| + ReadNextCommandSoon();
|
| }
|
|
|
| void HostController::StartForwarder(
|
| @@ -117,37 +131,34 @@ void HostController::StartForwarder(
|
| }
|
| // Open the Adb data connection, and send a command with the
|
| // |device_forward_port| as a way for the device to identify the connection.
|
| - SendCommand(command::DATA_CONNECTION,
|
| - device_port_,
|
| - adb_data_socket.get());
|
| + SendCommand(command::DATA_CONNECTION, device_port_, adb_data_socket.get());
|
|
|
| // Check that the device received the new Adb Data Connection. Note that this
|
| // check is done through the |adb_control_socket_| that is handled in the
|
| // DeviceListener thread just after the call to WaitForAdbDataSocket().
|
| if (!ReceivedCommand(command::ADB_DATA_SOCKET_SUCCESS,
|
| - &adb_control_socket_)) {
|
| + adb_control_socket_.get())) {
|
| LOG(ERROR) << "Device could not handle the new Adb Data Connection.";
|
| SelfDelete();
|
| return;
|
| }
|
| - Forwarder* forwarder = new Forwarder(host_server_data_socket.Pass(),
|
| - adb_data_socket.Pass());
|
| - // Forwarder object will self delete after returning.
|
| - forwarder->Start();
|
| + forwarder2::StartForwarder(
|
| + host_server_data_socket.Pass(), adb_data_socket.Pass());
|
| }
|
|
|
| scoped_ptr<Socket> HostController::CreateSocket() {
|
| scoped_ptr<Socket> socket(new Socket());
|
| socket->AddEventFd(global_exit_notifier_fd_);
|
| - socket->AddEventFd(delete_controller_notifier_.receiver_fd());
|
| + socket->AddEventFd(delete_controller_notifier_->receiver_fd());
|
| return socket.Pass();
|
| }
|
|
|
| void HostController::SelfDelete() {
|
| - base::ScopedClosureRunner delete_runner(
|
| - base::Bind(
|
| - &DeleteCallback::Run, base::Unretained(&delete_callback_),
|
| - base::Unretained(this)));
|
| + scoped_ptr<HostController> self_deleter(this);
|
| + deletion_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&HostController::SelfDeleteOnDeletionTaskRunner,
|
| + deletion_callback_, base::Passed(&self_deleter)));
|
| // Tell the device to delete its corresponding controller instance before we
|
| // self-delete.
|
| Socket socket;
|
| @@ -155,14 +166,21 @@ void HostController::SelfDelete() {
|
| LOG(ERROR) << "Could not connect to device on port " << adb_port_;
|
| return;
|
| }
|
| - if (!SendCommand(command::UNMAP_PORT, device_port_, &socket)) {
|
| + if (!SendCommand(command::UNLISTEN, device_port_, &socket)) {
|
| LOG(ERROR) << "Could not send unmap command for port " << device_port_;
|
| return;
|
| }
|
| - if (!ReceivedCommand(command::UNMAP_PORT_SUCCESS, &socket)) {
|
| + if (!ReceivedCommand(command::UNLISTEN_SUCCESS, &socket)) {
|
| LOG(ERROR) << "Unamp command failed for port " << device_port_;
|
| return;
|
| }
|
| }
|
|
|
| +// static
|
| +void HostController::SelfDeleteOnDeletionTaskRunner(
|
| + const DeletionCallback& deletion_callback,
|
| + scoped_ptr<HostController> controller) {
|
| + deletion_callback.Run(controller.Pass());
|
| +}
|
| +
|
| } // namespace forwarder2
|
|
|