OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/browser/devtools/device/android_device_manager.h" | 5 #include "chrome/browser/devtools/device/android_device_manager.h" |
6 | 6 |
7 #include "base/strings/string_number_conversions.h" | 7 #include "base/strings/string_number_conversions.h" |
8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "net/base/io_buffer.h" | 10 #include "net/base/io_buffer.h" |
11 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
12 #include "net/socket/stream_socket.h" | 12 #include "net/socket/stream_socket.h" |
13 | 13 |
14 namespace { | 14 namespace { |
15 | 15 |
16 const int kBufferSize = 16 * 1024; | 16 const int kBufferSize = 16 * 1024; |
17 | 17 |
| 18 static const char kModelOffline[] = "Offline"; |
| 19 |
18 static const char kHttpGetRequest[] = "GET %s HTTP/1.1\r\n\r\n"; | 20 static const char kHttpGetRequest[] = "GET %s HTTP/1.1\r\n\r\n"; |
19 | 21 |
20 static const char kWebSocketUpgradeRequest[] = "GET %s HTTP/1.1\r\n" | 22 static const char kWebSocketUpgradeRequest[] = "GET %s HTTP/1.1\r\n" |
21 "Upgrade: WebSocket\r\n" | 23 "Upgrade: WebSocket\r\n" |
22 "Connection: Upgrade\r\n" | 24 "Connection: Upgrade\r\n" |
23 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | 25 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" |
24 "Sec-WebSocket-Version: 13\r\n" | 26 "Sec-WebSocket-Version: 13\r\n" |
25 "\r\n"; | 27 "\r\n"; |
26 | 28 |
| 29 static void PostDeviceInfoCallback( |
| 30 scoped_refptr<base::MessageLoopProxy> response_message_loop, |
| 31 const AndroidDeviceManager::DeviceInfoCallback& callback, |
| 32 const AndroidDeviceManager::DeviceInfo& device_info) { |
| 33 response_message_loop->PostTask(FROM_HERE, base::Bind(callback, device_info)); |
| 34 } |
| 35 |
| 36 static void PostCommandCallback( |
| 37 scoped_refptr<base::MessageLoopProxy> response_message_loop, |
| 38 const AndroidDeviceManager::CommandCallback& callback, |
| 39 int result, |
| 40 const std::string& response) { |
| 41 response_message_loop->PostTask(FROM_HERE, |
| 42 base::Bind(callback, result, response)); |
| 43 } |
| 44 |
| 45 static void PostSocketCallback( |
| 46 scoped_refptr<base::MessageLoopProxy> response_message_loop, |
| 47 const AndroidDeviceManager::SocketCallback& callback, |
| 48 int result, |
| 49 net::StreamSocket* socket) { |
| 50 response_message_loop->PostTask(FROM_HERE, |
| 51 base::Bind(callback, result, socket)); |
| 52 } |
| 53 |
27 class HttpRequest { | 54 class HttpRequest { |
28 public: | 55 public: |
29 typedef AndroidDeviceManager::CommandCallback CommandCallback; | 56 typedef AndroidDeviceManager::CommandCallback CommandCallback; |
30 typedef AndroidDeviceManager::SocketCallback SocketCallback; | 57 typedef AndroidDeviceManager::SocketCallback SocketCallback; |
31 | 58 |
32 static void CommandRequest(const std::string& request, | 59 static void CommandRequest(const std::string& request, |
33 const CommandCallback& callback, | 60 const CommandCallback& callback, |
34 int result, | 61 int result, |
35 net::StreamSocket* socket) { | 62 net::StreamSocket* socket) { |
36 if (result != net::OK) { | 63 if (result != net::OK) { |
37 callback.Run(result, std::string()); | 64 callback.Run(result, std::string()); |
38 return; | 65 return; |
39 } | 66 } |
40 new HttpRequest(socket, request, callback); | 67 new HttpRequest(socket, request, callback); |
41 } | 68 } |
42 | 69 |
43 static void SocketRequest(const std::string& request, | 70 static void SocketRequest(const std::string& request, |
44 const SocketCallback& callback, | 71 const SocketCallback& callback, |
45 int result, | 72 int result, |
46 net::StreamSocket* socket) { | 73 net::StreamSocket* socket) { |
47 if (result != net::OK) { | 74 if (result != net::OK) { |
48 callback.Run(result, NULL); | 75 callback.Run(result, NULL); |
49 return; | 76 return; |
50 } | 77 } |
51 new HttpRequest(socket, request, callback); | 78 new HttpRequest(socket, request, callback); |
52 } | 79 } |
53 | 80 |
54 private: | 81 private: |
55 HttpRequest(net::StreamSocket* socket, | 82 HttpRequest(net::StreamSocket* socket, |
56 const std::string& request, | 83 const std::string& request, |
57 const CommandCallback& callback) | 84 const CommandCallback& callback) |
58 : socket_(socket), | 85 : socket_(socket), command_callback_(callback), body_pos_(0) { |
59 command_callback_(callback), | |
60 body_pos_(0) { | |
61 SendRequest(request); | 86 SendRequest(request); |
62 } | 87 } |
63 | 88 |
64 HttpRequest(net::StreamSocket* socket, | 89 HttpRequest(net::StreamSocket* socket, |
65 const std::string& request, | 90 const std::string& request, |
66 const SocketCallback& callback) | 91 const SocketCallback& callback) |
67 : socket_(socket), | 92 : socket_(socket), |
68 socket_callback_(callback), | 93 socket_callback_(callback), |
69 body_pos_(0) { | 94 body_pos_(0) { |
70 SendRequest(request); | 95 SendRequest(request); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 return false; | 192 return false; |
168 } | 193 } |
169 | 194 |
170 scoped_ptr<net::StreamSocket> socket_; | 195 scoped_ptr<net::StreamSocket> socket_; |
171 std::string response_; | 196 std::string response_; |
172 AndroidDeviceManager::CommandCallback command_callback_; | 197 AndroidDeviceManager::CommandCallback command_callback_; |
173 AndroidDeviceManager::SocketCallback socket_callback_; | 198 AndroidDeviceManager::SocketCallback socket_callback_; |
174 size_t body_pos_; | 199 size_t body_pos_; |
175 }; | 200 }; |
176 | 201 |
| 202 class DevicesRequest : public base::RefCountedThreadSafe<DevicesRequest> { |
| 203 public: |
| 204 typedef AndroidDeviceManager::DeviceInfo DeviceInfo; |
| 205 typedef AndroidDeviceManager::DeviceProvider DeviceProvider; |
| 206 typedef AndroidDeviceManager::DeviceProviders DeviceProviders; |
| 207 typedef AndroidDeviceManager::DeviceDescriptors DeviceDescriptors; |
| 208 typedef base::Callback<void(const DeviceDescriptors&)> DescriptorsCallback; |
| 209 |
| 210 static void Start(scoped_refptr<base::MessageLoopProxy> device_message_loop, |
| 211 const DeviceProviders& providers, |
| 212 const DescriptorsCallback& callback) { |
| 213 // Don't keep counted reference on calling thread; |
| 214 DevicesRequest* request = new DevicesRequest(callback); |
| 215 // Avoid destruction while sending requests |
| 216 request->AddRef(); |
| 217 for (DeviceProviders::const_iterator it = providers.begin(); |
| 218 it != providers.end(); |
| 219 ++it) { |
| 220 device_message_loop->PostTask( |
| 221 FROM_HERE, |
| 222 base::Bind( |
| 223 &DeviceProvider::QueryDevices, |
| 224 *it, |
| 225 base::Bind(&DevicesRequest::ProcessSerials, request, *it))); |
| 226 } |
| 227 device_message_loop->ReleaseSoon(FROM_HERE, request); |
| 228 } |
| 229 |
| 230 private: |
| 231 explicit DevicesRequest(const DescriptorsCallback& callback) |
| 232 : response_message_loop_(base::MessageLoopProxy::current()), |
| 233 callback_(callback) {} |
| 234 |
| 235 friend class base::RefCountedThreadSafe<DevicesRequest>; |
| 236 ~DevicesRequest() { |
| 237 response_message_loop_->PostTask(FROM_HERE, |
| 238 base::Bind(callback_, descriptors_)); |
| 239 } |
| 240 |
| 241 typedef std::vector<std::string> Serials; |
| 242 |
| 243 void ProcessSerials(scoped_refptr<DeviceProvider> provider, |
| 244 const Serials& serials) { |
| 245 for (Serials::const_iterator it = serials.begin(); it != serials.end(); |
| 246 ++it) { |
| 247 descriptors_.resize(descriptors_.size() + 1); |
| 248 descriptors_.back().provider = provider; |
| 249 descriptors_.back().serial = *it; |
| 250 } |
| 251 } |
| 252 |
| 253 scoped_refptr<base::MessageLoopProxy> response_message_loop_; |
| 254 DescriptorsCallback callback_; |
| 255 DeviceDescriptors descriptors_; |
| 256 }; |
| 257 |
177 } // namespace | 258 } // namespace |
178 | 259 |
179 AndroidDeviceManager::BrowserInfo::BrowserInfo() | 260 AndroidDeviceManager::BrowserInfo::BrowserInfo() |
180 : type(kTypeOther) { | 261 : type(kTypeOther) { |
181 } | 262 } |
182 | 263 |
183 AndroidDeviceManager::DeviceInfo::DeviceInfo() { | 264 AndroidDeviceManager::DeviceInfo::DeviceInfo() |
| 265 : model(kModelOffline), connected(false) { |
184 } | 266 } |
185 | 267 |
186 AndroidDeviceManager::DeviceInfo::~DeviceInfo() { | 268 AndroidDeviceManager::DeviceInfo::~DeviceInfo() { |
187 } | 269 } |
188 | 270 |
189 AndroidDeviceManager::Device::Device(const std::string& serial, | 271 void AndroidDeviceManager::DeviceProvider::SendJsonRequest( |
190 bool is_connected) | 272 const std::string& serial, |
191 : serial_(serial), | 273 const std::string& socket_name, |
192 is_connected_(is_connected) { | 274 const std::string& request, |
| 275 const CommandCallback& callback) { |
| 276 OpenSocket(serial, |
| 277 socket_name, |
| 278 base::Bind(&HttpRequest::CommandRequest, |
| 279 base::StringPrintf(kHttpGetRequest, request.c_str()), |
| 280 callback)); |
193 } | 281 } |
194 | 282 |
195 void AndroidDeviceManager::Device::HttpQuery(const std::string& socket_name, | 283 void AndroidDeviceManager::DeviceProvider::HttpUpgrade( |
196 const std::string& path, | 284 const std::string& serial, |
197 const CommandCallback& callback) { | 285 const std::string& socket_name, |
198 std::string request(base::StringPrintf(kHttpGetRequest, path.c_str())); | 286 const std::string& url, |
199 OpenSocket(socket_name, | 287 const SocketCallback& callback) { |
200 base::Bind(&HttpRequest::CommandRequest, request, callback)); | 288 OpenSocket( |
| 289 serial, |
| 290 socket_name, |
| 291 base::Bind(&HttpRequest::SocketRequest, |
| 292 base::StringPrintf(kWebSocketUpgradeRequest, url.c_str()), |
| 293 callback)); |
201 } | 294 } |
202 | 295 |
203 AndroidDeviceManager::Device::~Device() { | 296 void AndroidDeviceManager::DeviceProvider::ReleaseDevice( |
| 297 const std::string& serial) { |
204 } | 298 } |
205 | 299 |
206 AndroidDeviceManager::DeviceProvider::DeviceProvider() { | 300 AndroidDeviceManager::DeviceProvider::DeviceProvider() { |
207 } | 301 } |
208 | 302 |
209 AndroidDeviceManager::DeviceProvider::~DeviceProvider() { | 303 AndroidDeviceManager::DeviceProvider::~DeviceProvider() { |
210 } | 304 } |
211 | 305 |
| 306 void AndroidDeviceManager::Device::QueryDeviceInfo( |
| 307 const DeviceInfoCallback& callback) { |
| 308 device_message_loop_->PostTask( |
| 309 FROM_HERE, |
| 310 base::Bind(&DeviceProvider::QueryDeviceInfo, |
| 311 provider_, |
| 312 serial_, |
| 313 base::Bind(&PostDeviceInfoCallback, |
| 314 base::MessageLoopProxy::current(), |
| 315 callback))); |
| 316 } |
| 317 |
| 318 void AndroidDeviceManager::Device::OpenSocket(const std::string& socket_name, |
| 319 const SocketCallback& callback) { |
| 320 device_message_loop_->PostTask( |
| 321 FROM_HERE, |
| 322 base::Bind(&DeviceProvider::OpenSocket, |
| 323 provider_, |
| 324 serial_, |
| 325 socket_name, |
| 326 base::Bind(&PostSocketCallback, |
| 327 base::MessageLoopProxy::current(), |
| 328 callback))); |
| 329 } |
| 330 |
| 331 void AndroidDeviceManager::Device::SendJsonRequest( |
| 332 const std::string& socket_name, |
| 333 const std::string& request, |
| 334 const CommandCallback& callback) { |
| 335 device_message_loop_->PostTask( |
| 336 FROM_HERE, |
| 337 base::Bind(&DeviceProvider::SendJsonRequest, |
| 338 provider_, |
| 339 serial_, |
| 340 socket_name, |
| 341 request, |
| 342 base::Bind(&PostCommandCallback, |
| 343 base::MessageLoopProxy::current(), |
| 344 callback))); |
| 345 } |
| 346 |
| 347 void AndroidDeviceManager::Device::HttpUpgrade(const std::string& socket_name, |
| 348 const std::string& url, |
| 349 const SocketCallback& callback) { |
| 350 device_message_loop_->PostTask( |
| 351 FROM_HERE, |
| 352 base::Bind(&DeviceProvider::HttpUpgrade, |
| 353 provider_, |
| 354 serial_, |
| 355 socket_name, |
| 356 url, |
| 357 base::Bind(&PostSocketCallback, |
| 358 base::MessageLoopProxy::current(), |
| 359 callback))); |
| 360 } |
| 361 |
| 362 AndroidDeviceManager::Device::Device( |
| 363 scoped_refptr<base::MessageLoopProxy> device_message_loop, |
| 364 const scoped_refptr<DeviceProvider>& provider, |
| 365 const std::string& serial) |
| 366 : device_message_loop_(device_message_loop), |
| 367 provider_(provider), |
| 368 serial_(serial), |
| 369 weak_factory_(this) { |
| 370 } |
| 371 |
| 372 AndroidDeviceManager::Device::~Device() { |
| 373 device_message_loop_->PostTask( |
| 374 FROM_HERE, |
| 375 base::Bind(&DeviceProvider::ReleaseDevice, provider_, serial_)); |
| 376 } |
| 377 |
212 // static | 378 // static |
213 scoped_refptr<AndroidDeviceManager> AndroidDeviceManager::Create() { | 379 scoped_refptr<AndroidDeviceManager> AndroidDeviceManager::Create() { |
214 return new AndroidDeviceManager(); | 380 return new AndroidDeviceManager(); |
215 } | 381 } |
216 | 382 |
217 void AndroidDeviceManager::QueryDevices( | 383 void AndroidDeviceManager::QueryDevices( |
| 384 scoped_refptr<base::MessageLoopProxy> device_message_loop, |
218 const DeviceProviders& providers, | 385 const DeviceProviders& providers, |
219 const QueryDevicesCallback& callback) { | 386 const DevicesCallback& callback) { |
220 DCHECK(CalledOnValidThread()); | 387 DevicesRequest::Start(device_message_loop, |
221 stopped_ = false; | 388 providers, |
222 Devices empty; | 389 base::Bind(&AndroidDeviceManager::UpdateDevices, |
223 QueryNextProvider(callback, providers, empty, empty); | 390 this, |
| 391 device_message_loop, |
| 392 callback)); |
224 } | 393 } |
225 | 394 |
226 void AndroidDeviceManager::Stop() { | 395 AndroidDeviceManager::AndroidDeviceManager() { |
227 DCHECK(CalledOnValidThread()); | |
228 stopped_ = true; | |
229 devices_.clear(); | |
230 } | |
231 | |
232 bool AndroidDeviceManager::IsConnected(const std::string& serial) { | |
233 DCHECK(CalledOnValidThread()); | |
234 Device* device = FindDevice(serial); | |
235 return device && device->is_connected(); | |
236 } | |
237 | |
238 void AndroidDeviceManager::QueryDeviceInfo(const std::string& serial, | |
239 const DeviceInfoCallback& callback) { | |
240 DCHECK(CalledOnValidThread()); | |
241 Device* device = FindDevice(serial); | |
242 if (device) | |
243 device->QueryDeviceInfo(callback); | |
244 else | |
245 callback.Run(DeviceInfo()); | |
246 } | |
247 | |
248 void AndroidDeviceManager::OpenSocket( | |
249 const std::string& serial, | |
250 const std::string& socket_name, | |
251 const SocketCallback& callback) { | |
252 DCHECK(CalledOnValidThread()); | |
253 Device* device = FindDevice(serial); | |
254 if (device) | |
255 device->OpenSocket(socket_name, callback); | |
256 else | |
257 callback.Run(net::ERR_CONNECTION_FAILED, NULL); | |
258 } | |
259 | |
260 void AndroidDeviceManager::HttpQuery( | |
261 const std::string& serial, | |
262 const std::string& socket_name, | |
263 const std::string& request, | |
264 const CommandCallback& callback) { | |
265 DCHECK(CalledOnValidThread()); | |
266 Device* device = FindDevice(serial); | |
267 if (device) | |
268 device->HttpQuery(socket_name, request, callback); | |
269 else | |
270 callback.Run(net::ERR_CONNECTION_FAILED, std::string()); | |
271 } | |
272 | |
273 void AndroidDeviceManager::HttpUpgrade( | |
274 const std::string& serial, | |
275 const std::string& socket_name, | |
276 const std::string& url, | |
277 const SocketCallback& callback) { | |
278 DCHECK(CalledOnValidThread()); | |
279 Device* device = FindDevice(serial); | |
280 if (device) { | |
281 device->OpenSocket( | |
282 socket_name, | |
283 base::Bind(&HttpRequest::SocketRequest, | |
284 base::StringPrintf(kWebSocketUpgradeRequest, url.c_str()), | |
285 callback)); | |
286 } else { | |
287 callback.Run(net::ERR_CONNECTION_FAILED, NULL); | |
288 } | |
289 } | |
290 | |
291 AndroidDeviceManager::AndroidDeviceManager() | |
292 : stopped_(false) { | |
293 } | 396 } |
294 | 397 |
295 AndroidDeviceManager::~AndroidDeviceManager() { | 398 AndroidDeviceManager::~AndroidDeviceManager() { |
296 } | 399 } |
297 | 400 |
298 void AndroidDeviceManager::QueryNextProvider( | 401 void AndroidDeviceManager::UpdateDevices( |
299 const QueryDevicesCallback& callback, | 402 scoped_refptr<base::MessageLoopProxy> device_message_loop, |
300 const DeviceProviders& providers, | 403 const DevicesCallback& callback, |
301 const Devices& total_devices, | 404 const DeviceDescriptors& descriptors) { |
302 const Devices& new_devices) { | 405 Devices response; |
303 DCHECK(CalledOnValidThread()); | 406 DeviceWeakMap new_devices; |
304 | 407 for (DeviceDescriptors::const_iterator it = descriptors.begin(); |
305 if (stopped_) | 408 it != descriptors.end(); |
306 return; | 409 ++it) { |
307 | 410 DeviceWeakMap::iterator found = devices_.find(it->serial); |
308 Devices more_devices(total_devices); | 411 scoped_refptr<Device> device; |
309 more_devices.insert( | 412 if (found == devices_.end() || !found->second) { |
310 more_devices.end(), new_devices.begin(), new_devices.end()); | 413 device = new Device(device_message_loop, it->provider, it->serial); |
311 | 414 } else { |
312 if (providers.empty()) { | 415 device = found->second.get(); |
313 std::vector<std::string> serials; | |
314 devices_.clear(); | |
315 for (Devices::const_iterator it = more_devices.begin(); | |
316 it != more_devices.end(); ++it) { | |
317 devices_[(*it)->serial()] = *it; | |
318 serials.push_back((*it)->serial()); | |
319 } | 416 } |
320 callback.Run(serials); | 417 response.push_back(device); |
321 return; | 418 new_devices[it->serial] = device->weak_factory_.GetWeakPtr(); |
322 } | 419 } |
323 | 420 devices_.swap(new_devices); |
324 scoped_refptr<DeviceProvider> current_provider = providers.back(); | 421 callback.Run(response); |
325 DeviceProviders less_providers = providers; | |
326 less_providers.pop_back(); | |
327 current_provider->QueryDevices( | |
328 base::Bind(&AndroidDeviceManager::QueryNextProvider, | |
329 this, callback, less_providers, more_devices)); | |
330 } | 422 } |
331 | |
332 AndroidDeviceManager::Device* | |
333 AndroidDeviceManager::FindDevice(const std::string& serial) { | |
334 DCHECK(CalledOnValidThread()); | |
335 DeviceMap::const_iterator it = devices_.find(serial); | |
336 if (it == devices_.end()) | |
337 return NULL; | |
338 return (*it).second.get(); | |
339 } | |
OLD | NEW |