| 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 |