OLD | NEW |
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 <errno.h> | 5 #include <errno.h> |
6 #include <signal.h> | 6 #include <signal.h> |
7 #include <sys/types.h> | 7 #include <sys/types.h> |
8 #include <sys/wait.h> | 8 #include <sys/wait.h> |
9 #include <unistd.h> | 9 #include <unistd.h> |
10 | 10 |
11 #include <cstdio> | 11 #include <cstdio> |
12 #include <iostream> | 12 #include <iostream> |
13 #include <limits> | 13 #include <limits> |
14 #include <string> | 14 #include <string> |
15 #include <utility> | 15 #include <utility> |
16 #include <vector> | 16 #include <vector> |
17 | 17 |
18 #include "base/at_exit.h" | 18 #include "base/at_exit.h" |
| 19 #include "base/basictypes.h" |
19 #include "base/bind.h" | 20 #include "base/bind.h" |
20 #include "base/command_line.h" | 21 #include "base/command_line.h" |
21 #include "base/compiler_specific.h" | 22 #include "base/compiler_specific.h" |
22 #include "base/containers/hash_tables.h" | 23 #include "base/containers/hash_tables.h" |
23 #include "base/file_util.h" | 24 #include "base/file_util.h" |
24 #include "base/files/file_path.h" | 25 #include "base/files/file_path.h" |
25 #include "base/logging.h" | 26 #include "base/logging.h" |
26 #include "base/memory/linked_ptr.h" | 27 #include "base/memory/linked_ptr.h" |
27 #include "base/memory/scoped_vector.h" | 28 #include "base/memory/scoped_vector.h" |
| 29 #include "base/memory/weak_ptr.h" |
28 #include "base/pickle.h" | 30 #include "base/pickle.h" |
29 #include "base/posix/eintr_wrapper.h" | 31 #include "base/posix/eintr_wrapper.h" |
30 #include "base/safe_strerror_posix.h" | 32 #include "base/safe_strerror_posix.h" |
31 #include "base/strings/string_number_conversions.h" | 33 #include "base/strings/string_number_conversions.h" |
32 #include "base/strings/string_piece.h" | 34 #include "base/strings/string_piece.h" |
33 #include "base/strings/string_split.h" | 35 #include "base/strings/string_split.h" |
34 #include "base/strings/string_util.h" | 36 #include "base/strings/string_util.h" |
35 #include "base/strings/stringprintf.h" | 37 #include "base/strings/stringprintf.h" |
36 #include "base/task_runner.h" | 38 #include "base/task_runner.h" |
37 #include "base/threading/thread.h" | 39 #include "base/threading/thread.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 static int s_kill_handler_count = 0; | 75 static int s_kill_handler_count = 0; |
74 CHECK(g_notifier); | 76 CHECK(g_notifier); |
75 // If for some reason the forwarder get stuck in any socket waiting forever, | 77 // If for some reason the forwarder get stuck in any socket waiting forever, |
76 // we can send a SIGKILL or SIGINT three times to force it die | 78 // we can send a SIGKILL or SIGINT three times to force it die |
77 // (non-nicely). This is useful when debugging. | 79 // (non-nicely). This is useful when debugging. |
78 ++s_kill_handler_count; | 80 ++s_kill_handler_count; |
79 if (!g_notifier->Notify() || s_kill_handler_count > 2) | 81 if (!g_notifier->Notify() || s_kill_handler_count > 2) |
80 exit(1); | 82 exit(1); |
81 } | 83 } |
82 | 84 |
| 85 // Manages HostController instances. There is one HostController instance for |
| 86 // each connection being forwarded. Note that forwarding can happen with many |
| 87 // devices (identified with a serial id). |
83 class HostControllersManager { | 88 class HostControllersManager { |
84 public: | 89 public: |
85 HostControllersManager() : has_failed_(false) {} | 90 HostControllersManager() |
| 91 : weak_ptr_factory_(this), |
| 92 controllers_(new HostControllerMap()), |
| 93 has_failed_(false) { |
| 94 } |
| 95 |
| 96 ~HostControllersManager() { |
| 97 if (!thread_.get()) |
| 98 return; |
| 99 // Delete the controllers on the thread they were created on. |
| 100 thread_->message_loop_proxy()->DeleteSoon( |
| 101 FROM_HERE, controllers_.release()); |
| 102 } |
86 | 103 |
87 void HandleRequest(const std::string& device_serial, | 104 void HandleRequest(const std::string& device_serial, |
88 int device_port, | 105 int device_port, |
89 int host_port, | 106 int host_port, |
90 scoped_ptr<Socket> client_socket) { | 107 scoped_ptr<Socket> client_socket) { |
91 // Lazy initialize so that the CLI process doesn't get this thread created. | 108 // Lazy initialize so that the CLI process doesn't get this thread created. |
92 InitOnce(); | 109 InitOnce(); |
93 thread_->message_loop_proxy()->PostTask( | 110 thread_->message_loop_proxy()->PostTask( |
94 FROM_HERE, | 111 FROM_HERE, |
95 base::Bind( | 112 base::Bind( |
(...skipping 14 matching lines...) Expand all Loading... |
110 | 127 |
111 void InitOnce() { | 128 void InitOnce() { |
112 if (thread_.get()) | 129 if (thread_.get()) |
113 return; | 130 return; |
114 at_exit_manager_.reset(new base::AtExitManager()); | 131 at_exit_manager_.reset(new base::AtExitManager()); |
115 thread_.reset(new base::Thread("HostControllersManagerThread")); | 132 thread_.reset(new base::Thread("HostControllersManagerThread")); |
116 thread_->Start(); | 133 thread_->Start(); |
117 } | 134 } |
118 | 135 |
119 // Invoked when a HostController instance reports an error (e.g. due to a | 136 // Invoked when a HostController instance reports an error (e.g. due to a |
120 // device connectivity issue). | 137 // device connectivity issue). Note that this could be called after the |
121 void DeleteHostController(HostController* host_controller) { | 138 // controller manager was destroyed which is why a weak pointer is used. |
122 if (!thread_->message_loop_proxy()->RunsTasksOnCurrentThread()) { | 139 static void DeleteHostController( |
123 // This can be invoked from the host controller internal thread. | 140 const base::WeakPtr<HostControllersManager>& manager_ptr, |
124 thread_->message_loop_proxy()->PostTask( | 141 scoped_ptr<HostController> host_controller) { |
125 FROM_HERE, | 142 HostController* const controller = host_controller.release(); |
126 base::Bind( | 143 HostControllersManager* const manager = manager_ptr.get(); |
127 &HostControllersManager::DeleteHostControllerOnInternalThread, | 144 if (!manager) { |
128 base::Unretained(this), host_controller)); | 145 // Note that |controller| is not leaked in this case since the host |
| 146 // controllers manager owns the controllers. If the manager was deleted |
| 147 // then all the controllers (including |controller|) were also deleted. |
129 return; | 148 return; |
130 } | 149 } |
131 DeleteHostControllerOnInternalThread(host_controller); | 150 DCHECK(manager->thread_->message_loop_proxy()->RunsTasksOnCurrentThread()); |
132 } | 151 // Note that this will delete |controller| which is owned by the map. |
133 | 152 manager->controllers_->erase( |
134 void DeleteHostControllerOnInternalThread(HostController* host_controller) { | 153 MakeHostControllerMapKey(controller->adb_port(), |
135 // Note that this will delete |host_controller| which is owned by the map. | 154 controller->device_port())); |
136 controllers_.erase( | |
137 MakeHostControllerMapKey(host_controller->adb_port(), | |
138 host_controller->device_port())); | |
139 } | 155 } |
140 | 156 |
141 void HandleRequestOnInternalThread(const std::string& device_serial, | 157 void HandleRequestOnInternalThread(const std::string& device_serial, |
142 int device_port, | 158 int device_port, |
143 int host_port, | 159 int host_port, |
144 scoped_ptr<Socket> client_socket) { | 160 scoped_ptr<Socket> client_socket) { |
145 const int adb_port = GetAdbPortForDevice(device_serial); | 161 const int adb_port = GetAdbPortForDevice(device_serial); |
146 if (adb_port < 0) { | 162 if (adb_port < 0) { |
147 SendMessage( | 163 SendMessage( |
148 "ERROR: could not get adb port for device. You might need to add " | 164 "ERROR: could not get adb port for device. You might need to add " |
149 "'adb' to your PATH or provide the device serial id.", | 165 "'adb' to your PATH or provide the device serial id.", |
150 client_socket.get()); | 166 client_socket.get()); |
151 return; | 167 return; |
152 } | 168 } |
153 if (device_port < 0) { | 169 if (device_port < 0) { |
154 // Remove the previously created host controller. | 170 // Remove the previously created host controller. |
155 const std::string controller_key = MakeHostControllerMapKey( | 171 const std::string controller_key = MakeHostControllerMapKey( |
156 adb_port, -device_port); | 172 adb_port, -device_port); |
157 const HostControllerMap::size_type removed_elements = controllers_.erase( | 173 const HostControllerMap::size_type removed_elements = controllers_->erase( |
158 controller_key); | 174 controller_key); |
159 SendMessage( | 175 SendMessage( |
160 !removed_elements ? "ERROR: could not unmap port" : "OK", | 176 !removed_elements ? "ERROR: could not unmap port" : "OK", |
161 client_socket.get()); | 177 client_socket.get()); |
162 return; | 178 return; |
163 } | 179 } |
164 if (host_port < 0) { | 180 if (host_port < 0) { |
165 SendMessage("ERROR: missing host port", client_socket.get()); | 181 SendMessage("ERROR: missing host port", client_socket.get()); |
166 return; | 182 return; |
167 } | 183 } |
168 const bool use_dynamic_port_allocation = device_port == 0; | 184 const bool use_dynamic_port_allocation = device_port == 0; |
169 if (!use_dynamic_port_allocation) { | 185 if (!use_dynamic_port_allocation) { |
170 const std::string controller_key = MakeHostControllerMapKey( | 186 const std::string controller_key = MakeHostControllerMapKey( |
171 adb_port, device_port); | 187 adb_port, device_port); |
172 if (controllers_.find(controller_key) != controllers_.end()) { | 188 if (controllers_->find(controller_key) != controllers_->end()) { |
173 LOG(INFO) << "Already forwarding device port " << device_port | 189 LOG(INFO) << "Already forwarding device port " << device_port |
174 << " to host port " << host_port; | 190 << " to host port " << host_port; |
175 SendMessage(base::StringPrintf("%d:%d", device_port, host_port), | 191 SendMessage(base::StringPrintf("%d:%d", device_port, host_port), |
176 client_socket.get()); | 192 client_socket.get()); |
177 return; | 193 return; |
178 } | 194 } |
179 } | 195 } |
180 // Create a new host controller. | 196 // Create a new host controller. |
181 scoped_ptr<HostController> host_controller( | 197 scoped_ptr<HostController> host_controller( |
182 new HostController( | 198 HostController::Create( |
183 device_port, "127.0.0.1", host_port, adb_port, GetExitNotifierFD(), | 199 device_port, host_port, adb_port, GetExitNotifierFD(), |
184 base::Bind(&HostControllersManager::DeleteHostController, | 200 base::Bind(&HostControllersManager::DeleteHostController, |
185 base::Unretained(this)))); | 201 weak_ptr_factory_.GetWeakPtr()))); |
186 if (!host_controller->Connect()) { | 202 if (!host_controller.get()) { |
187 has_failed_ = true; | 203 has_failed_ = true; |
188 SendMessage("ERROR: Connection to device failed.", client_socket.get()); | 204 SendMessage("ERROR: Connection to device failed.", client_socket.get()); |
189 return; | 205 return; |
190 } | 206 } |
191 // Get the current allocated port. | 207 // Get the current allocated port. |
192 device_port = host_controller->device_port(); | 208 device_port = host_controller->device_port(); |
193 LOG(INFO) << "Forwarding device port " << device_port << " to host port " | 209 LOG(INFO) << "Forwarding device port " << device_port << " to host port " |
194 << host_port; | 210 << host_port; |
195 const std::string msg = base::StringPrintf("%d:%d", device_port, host_port); | 211 const std::string msg = base::StringPrintf("%d:%d", device_port, host_port); |
196 if (!SendMessage(msg, client_socket.get())) | 212 if (!SendMessage(msg, client_socket.get())) |
197 return; | 213 return; |
198 host_controller->Start(); | 214 host_controller->Start(); |
199 controllers_.insert( | 215 controllers_->insert( |
200 std::make_pair(MakeHostControllerMapKey(adb_port, device_port), | 216 std::make_pair(MakeHostControllerMapKey(adb_port, device_port), |
201 linked_ptr<HostController>(host_controller.release()))); | 217 linked_ptr<HostController>(host_controller.release()))); |
202 } | 218 } |
203 | 219 |
204 int GetAdbPortForDevice(const std::string& device_serial) { | 220 int GetAdbPortForDevice(const std::string& device_serial) { |
205 base::hash_map<std::string, int>::const_iterator it = | 221 base::hash_map<std::string, int>::const_iterator it = |
206 device_serial_to_adb_port_map_.find(device_serial); | 222 device_serial_to_adb_port_map_.find(device_serial); |
207 if (it != device_serial_to_adb_port_map_.end()) | 223 if (it != device_serial_to_adb_port_map_.end()) |
208 return it->second; | 224 return it->second; |
209 Socket bind_socket; | 225 Socket bind_socket; |
(...skipping 15 matching lines...) Expand all Loading... |
225 } | 241 } |
226 | 242 |
227 bool SendMessage(const std::string& msg, Socket* client_socket) { | 243 bool SendMessage(const std::string& msg, Socket* client_socket) { |
228 bool result = client_socket->WriteString(msg); | 244 bool result = client_socket->WriteString(msg); |
229 DCHECK(result); | 245 DCHECK(result); |
230 if (!result) | 246 if (!result) |
231 has_failed_ = true; | 247 has_failed_ = true; |
232 return result; | 248 return result; |
233 } | 249 } |
234 | 250 |
| 251 base::WeakPtrFactory<HostControllersManager> weak_ptr_factory_; |
235 base::hash_map<std::string, int> device_serial_to_adb_port_map_; | 252 base::hash_map<std::string, int> device_serial_to_adb_port_map_; |
236 HostControllerMap controllers_; | 253 scoped_ptr<HostControllerMap> controllers_; |
237 bool has_failed_; | 254 bool has_failed_; |
238 scoped_ptr<base::AtExitManager> at_exit_manager_; // Needed by base::Thread. | 255 scoped_ptr<base::AtExitManager> at_exit_manager_; // Needed by base::Thread. |
239 scoped_ptr<base::Thread> thread_; | 256 scoped_ptr<base::Thread> thread_; |
240 }; | 257 }; |
241 | 258 |
242 class ServerDelegate : public Daemon::ServerDelegate { | 259 class ServerDelegate : public Daemon::ServerDelegate { |
243 public: | 260 public: |
244 ServerDelegate() : has_failed_(false) {} | 261 ServerDelegate() : has_failed_(false) {} |
245 | 262 |
246 bool has_failed() const { | 263 bool has_failed() const { |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 | 405 |
389 return client_delegate.has_failed() || daemon_delegate.has_failed(); | 406 return client_delegate.has_failed() || daemon_delegate.has_failed(); |
390 } | 407 } |
391 | 408 |
392 } // namespace | 409 } // namespace |
393 } // namespace forwarder2 | 410 } // namespace forwarder2 |
394 | 411 |
395 int main(int argc, char** argv) { | 412 int main(int argc, char** argv) { |
396 return forwarder2::RunHostForwarder(argc, argv); | 413 return forwarder2::RunHostForwarder(argc, argv); |
397 } | 414 } |
OLD | NEW |