Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Side by Side Diff: tools/android/forwarder2/host_controller.cc

Issue 19478003: Remove Thread wrapper class in forwarder2. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address Marcus' comments Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/android/forwarder2/host_controller.h" 5 #include "tools/android/forwarder2/host_controller.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "tools/android/forwarder2/command.h" 13 #include "tools/android/forwarder2/command.h"
14 #include "tools/android/forwarder2/forwarder.h" 14 #include "tools/android/forwarder2/forwarder.h"
15 #include "tools/android/forwarder2/socket.h" 15 #include "tools/android/forwarder2/socket.h"
16 16
17 namespace forwarder2 { 17 namespace forwarder2 {
18 18
19 HostController::HostController(int device_port, 19 // static
20 const std::string& forward_to_host, 20 scoped_ptr<HostController> HostController::Create(
21 int forward_to_host_port, 21 int device_port,
22 int adb_port, 22 int host_port,
23 int exit_notifier_fd, 23 int adb_port,
24 const DeleteCallback& delete_callback) 24 int exit_notifier_fd,
25 : device_port_(device_port), 25 const DeletionCallback& deletion_callback) {
26 forward_to_host_(forward_to_host), 26 scoped_ptr<HostController> host_controller;
27 forward_to_host_port_(forward_to_host_port), 27 scoped_ptr<PipeNotifier> delete_controller_notifier(new PipeNotifier());
28 adb_port_(adb_port), 28 scoped_ptr<Socket> adb_control_socket(new Socket());
29 global_exit_notifier_fd_(exit_notifier_fd), 29 adb_control_socket->AddEventFd(exit_notifier_fd);
30 delete_callback_(delete_callback), 30 adb_control_socket->AddEventFd(delete_controller_notifier->receiver_fd());
31 ready_(false), 31 if (!adb_control_socket->ConnectTcp(std::string(), adb_port)) {
32 thread_("HostControllerThread") { 32 LOG(ERROR) << "Could not connect HostController socket on port: "
33 adb_control_socket_.AddEventFd(global_exit_notifier_fd_); 33 << adb_port;
34 adb_control_socket_.AddEventFd(delete_controller_notifier_.receiver_fd()); 34 return host_controller.Pass();
35 }
36 // Send the command to the device start listening to the "device_forward_port"
37 bool send_command_success = SendCommand(
38 command::LISTEN, device_port, adb_control_socket.get());
39 CHECK(send_command_success);
40 int device_port_allocated;
41 command::Type command;
42 if (!ReadCommand(
43 adb_control_socket.get(), &device_port_allocated, &command) ||
44 command != command::BIND_SUCCESS) {
45 LOG(ERROR) << "Device binding error using port " << device_port;
46 return host_controller.Pass();
47 }
48 host_controller.reset(
49 new HostController(
50 device_port_allocated, host_port, adb_port, exit_notifier_fd,
51 deletion_callback, adb_control_socket.Pass(),
52 delete_controller_notifier.Pass()));
53 return host_controller.Pass();
35 } 54 }
36 55
37 HostController::~HostController() { 56 HostController::~HostController() {
38 delete_controller_notifier_.Notify(); 57 DCHECK(deletion_task_runner_->RunsTasksOnCurrentThread());
58 delete_controller_notifier_->Notify();
39 // Note that the Forwarder instance (that also received a delete notification) 59 // Note that the Forwarder instance (that also received a delete notification)
40 // might still be running on its own thread at this point. This is not a 60 // might still be running on its own thread at this point. This is not a
41 // problem since it will self-delete once the socket that it is operating on 61 // problem since it will self-delete once the socket that it is operating on
42 // is closed. 62 // is closed.
43 } 63 }
44 64
45 bool HostController::Connect() { 65 void HostController::Start() {
46 if (!adb_control_socket_.ConnectTcp("", adb_port_)) { 66 thread_.Start();
47 LOG(ERROR) << "Could not connect HostController socket on port: " 67 ReadNextCommandSoon();
48 << adb_port_;
49 SelfDelete();
50 return false;
51 }
52 // Send the command to the device start listening to the "device_forward_port"
53 bool send_command_success = SendCommand(
54 command::LISTEN, device_port_, &adb_control_socket_);
55 CHECK(send_command_success);
56 int device_port_allocated;
57 command::Type command;
58 if (!ReadCommand(&adb_control_socket_, &device_port_allocated, &command) ||
59 command != command::BIND_SUCCESS) {
60 LOG(ERROR) << "Device binding error using port " << device_port_;
61 SelfDelete();
62 return false;
63 }
64 // When doing dynamically allocation of port, we get the port from the
65 // BIND_SUCCESS command we received above.
66 device_port_ = device_port_allocated;
67 ready_ = true;
68 return true;
69 } 68 }
70 69
71 void HostController::Start() { 70 HostController::HostController(
72 thread_.Start(); 71 int device_port,
72 int host_port,
73 int adb_port,
74 int exit_notifier_fd,
75 const DeletionCallback& deletion_callback,
76 scoped_ptr<Socket> adb_control_socket,
77 scoped_ptr<PipeNotifier> delete_controller_notifier)
78 : device_port_(device_port),
79 host_port_(host_port),
80 adb_port_(adb_port),
81 global_exit_notifier_fd_(exit_notifier_fd),
82 deletion_callback_(deletion_callback),
83 adb_control_socket_(adb_control_socket.Pass()),
84 delete_controller_notifier_(delete_controller_notifier.Pass()),
85 deletion_task_runner_(base::MessageLoopProxy::current()),
86 thread_("HostControllerThread") {
87 }
88
89 void HostController::ReadNextCommandSoon() {
73 thread_.message_loop_proxy()->PostTask( 90 thread_.message_loop_proxy()->PostTask(
74 FROM_HERE, 91 FROM_HERE,
75 base::Bind(&HostController::ThreadHandler, base::Unretained(this))); 92 base::Bind(&HostController::ReadCommandOnInternalThread,
93 base::Unretained(this)));
76 } 94 }
77 95
78 void HostController::ThreadHandler() { 96 void HostController::ReadCommandOnInternalThread() {
79 CHECK(ready_) << "HostController not ready. Must call Connect() first."; 97 if (!ReceivedCommand(command::ACCEPT_SUCCESS, adb_control_socket_.get())) {
80 while (true) { 98 SelfDelete();
81 if (!ReceivedCommand(command::ACCEPT_SUCCESS, &adb_control_socket_)) { 99 return;
82 SelfDelete(); 100 }
101 // Try to connect to host server.
102 scoped_ptr<Socket> host_server_data_socket(CreateSocket());
103 if (!host_server_data_socket->ConnectTcp(std::string(), host_port_)) {
104 LOG(ERROR) << "Could not Connect HostServerData socket on port: "
105 << host_port_;
106 SendCommand(
107 command::HOST_SERVER_ERROR, device_port_, adb_control_socket_.get());
108 if (ReceivedCommand(command::ACK, adb_control_socket_.get())) {
109 // It can continue if the host forwarder could not connect to the host
110 // server but the device acknowledged that, so that the device could
111 // re-try later.
112 ReadNextCommandSoon();
83 return; 113 return;
84 } 114 }
85 // Try to connect to host server. 115 SelfDelete();
86 scoped_ptr<Socket> host_server_data_socket(CreateSocket()); 116 return;
87 if (!host_server_data_socket->ConnectTcp(
88 forward_to_host_, forward_to_host_port_)) {
89 LOG(ERROR) << "Could not Connect HostServerData socket on port: "
90 << forward_to_host_port_;
91 SendCommand(command::HOST_SERVER_ERROR,
92 device_port_,
93 &adb_control_socket_);
94 if (ReceivedCommand(command::ACK, &adb_control_socket_)) {
95 // It can continue if the host forwarder could not connect to the host
96 // server but the device acknowledged that, so that the device could
97 // re-try later.
98 continue;
99 }
100 SelfDelete();
101 return;
102 }
103 SendCommand(command::HOST_SERVER_SUCCESS,
104 device_port_,
105 &adb_control_socket_);
106 StartForwarder(host_server_data_socket.Pass());
107 } 117 }
118 SendCommand(
119 command::HOST_SERVER_SUCCESS, device_port_, adb_control_socket_.get());
120 StartForwarder(host_server_data_socket.Pass());
121 ReadNextCommandSoon();
108 } 122 }
109 123
110 void HostController::StartForwarder( 124 void HostController::StartForwarder(
111 scoped_ptr<Socket> host_server_data_socket) { 125 scoped_ptr<Socket> host_server_data_socket) {
112 scoped_ptr<Socket> adb_data_socket(CreateSocket()); 126 scoped_ptr<Socket> adb_data_socket(CreateSocket());
113 if (!adb_data_socket->ConnectTcp("", adb_port_)) { 127 if (!adb_data_socket->ConnectTcp("", adb_port_)) {
114 LOG(ERROR) << "Could not connect AdbDataSocket on port: " << adb_port_; 128 LOG(ERROR) << "Could not connect AdbDataSocket on port: " << adb_port_;
115 SelfDelete(); 129 SelfDelete();
116 return; 130 return;
117 } 131 }
118 // Open the Adb data connection, and send a command with the 132 // Open the Adb data connection, and send a command with the
119 // |device_forward_port| as a way for the device to identify the connection. 133 // |device_forward_port| as a way for the device to identify the connection.
120 SendCommand(command::DATA_CONNECTION, 134 SendCommand(command::DATA_CONNECTION, device_port_, adb_data_socket.get());
121 device_port_,
122 adb_data_socket.get());
123 135
124 // Check that the device received the new Adb Data Connection. Note that this 136 // Check that the device received the new Adb Data Connection. Note that this
125 // check is done through the |adb_control_socket_| that is handled in the 137 // check is done through the |adb_control_socket_| that is handled in the
126 // DeviceListener thread just after the call to WaitForAdbDataSocket(). 138 // DeviceListener thread just after the call to WaitForAdbDataSocket().
127 if (!ReceivedCommand(command::ADB_DATA_SOCKET_SUCCESS, 139 if (!ReceivedCommand(command::ADB_DATA_SOCKET_SUCCESS,
128 &adb_control_socket_)) { 140 adb_control_socket_.get())) {
129 LOG(ERROR) << "Device could not handle the new Adb Data Connection."; 141 LOG(ERROR) << "Device could not handle the new Adb Data Connection.";
130 SelfDelete(); 142 SelfDelete();
131 return; 143 return;
132 } 144 }
133 Forwarder* forwarder = new Forwarder(host_server_data_socket.Pass(), 145 forwarder2::StartForwarder(
134 adb_data_socket.Pass()); 146 host_server_data_socket.Pass(), adb_data_socket.Pass());
135 // Forwarder object will self delete after returning.
136 forwarder->Start();
137 } 147 }
138 148
139 scoped_ptr<Socket> HostController::CreateSocket() { 149 scoped_ptr<Socket> HostController::CreateSocket() {
140 scoped_ptr<Socket> socket(new Socket()); 150 scoped_ptr<Socket> socket(new Socket());
141 socket->AddEventFd(global_exit_notifier_fd_); 151 socket->AddEventFd(global_exit_notifier_fd_);
142 socket->AddEventFd(delete_controller_notifier_.receiver_fd()); 152 socket->AddEventFd(delete_controller_notifier_->receiver_fd());
143 return socket.Pass(); 153 return socket.Pass();
144 } 154 }
145 155
146 void HostController::SelfDelete() { 156 void HostController::SelfDelete() {
147 base::ScopedClosureRunner delete_runner( 157 scoped_ptr<HostController> self_deleter(this);
148 base::Bind( 158 deletion_task_runner_->PostTask(
149 &DeleteCallback::Run, base::Unretained(&delete_callback_), 159 FROM_HERE,
150 base::Unretained(this))); 160 base::Bind(&HostController::SelfDeleteOnDeletionTaskRunner,
161 deletion_callback_, base::Passed(&self_deleter)));
151 // Tell the device to delete its corresponding controller instance before we 162 // Tell the device to delete its corresponding controller instance before we
152 // self-delete. 163 // self-delete.
153 Socket socket; 164 Socket socket;
154 if (!socket.ConnectTcp("", adb_port_)) { 165 if (!socket.ConnectTcp("", adb_port_)) {
155 LOG(ERROR) << "Could not connect to device on port " << adb_port_; 166 LOG(ERROR) << "Could not connect to device on port " << adb_port_;
156 return; 167 return;
157 } 168 }
158 if (!SendCommand(command::UNMAP_PORT, device_port_, &socket)) { 169 if (!SendCommand(command::UNLISTEN, device_port_, &socket)) {
159 LOG(ERROR) << "Could not send unmap command for port " << device_port_; 170 LOG(ERROR) << "Could not send unmap command for port " << device_port_;
160 return; 171 return;
161 } 172 }
162 if (!ReceivedCommand(command::UNMAP_PORT_SUCCESS, &socket)) { 173 if (!ReceivedCommand(command::UNLISTEN_SUCCESS, &socket)) {
163 LOG(ERROR) << "Unamp command failed for port " << device_port_; 174 LOG(ERROR) << "Unamp command failed for port " << device_port_;
164 return; 175 return;
165 } 176 }
166 } 177 }
167 178
179 // static
180 void HostController::SelfDeleteOnDeletionTaskRunner(
181 const DeletionCallback& deletion_callback,
182 scoped_ptr<HostController> controller) {
183 deletion_callback.Run(controller.Pass());
184 }
185
168 } // namespace forwarder2 186 } // namespace forwarder2
OLDNEW
« no previous file with comments | « tools/android/forwarder2/host_controller.h ('k') | tools/android/forwarder2/host_forwarder_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698