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 using content::BrowserThread; |
| 15 |
14 namespace { | 16 namespace { |
15 | 17 |
| 18 const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread"; |
| 19 |
16 const int kBufferSize = 16 * 1024; | 20 const int kBufferSize = 16 * 1024; |
17 | 21 |
| 22 static const char kModelOffline[] = "Offline"; |
| 23 |
18 static const char kHttpGetRequest[] = "GET %s HTTP/1.1\r\n\r\n"; | 24 static const char kHttpGetRequest[] = "GET %s HTTP/1.1\r\n\r\n"; |
19 | 25 |
20 static const char kWebSocketUpgradeRequest[] = "GET %s HTTP/1.1\r\n" | 26 static const char kWebSocketUpgradeRequest[] = "GET %s HTTP/1.1\r\n" |
21 "Upgrade: WebSocket\r\n" | 27 "Upgrade: WebSocket\r\n" |
22 "Connection: Upgrade\r\n" | 28 "Connection: Upgrade\r\n" |
23 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | 29 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" |
24 "Sec-WebSocket-Version: 13\r\n" | 30 "Sec-WebSocket-Version: 13\r\n" |
25 "\r\n"; | 31 "\r\n"; |
26 | 32 |
| 33 static void PostDeviceInfoCallback( |
| 34 scoped_refptr<base::MessageLoopProxy> response_message_loop, |
| 35 const AndroidDeviceManager::DeviceInfoCallback& callback, |
| 36 const AndroidDeviceManager::DeviceInfo& device_info) { |
| 37 response_message_loop->PostTask(FROM_HERE, base::Bind(callback, device_info)); |
| 38 } |
| 39 |
| 40 static void PostCommandCallback( |
| 41 scoped_refptr<base::MessageLoopProxy> response_message_loop, |
| 42 const AndroidDeviceManager::CommandCallback& callback, |
| 43 int result, |
| 44 const std::string& response) { |
| 45 response_message_loop->PostTask(FROM_HERE, |
| 46 base::Bind(callback, result, response)); |
| 47 } |
| 48 |
| 49 static void PostSocketCallback( |
| 50 scoped_refptr<base::MessageLoopProxy> response_message_loop, |
| 51 const AndroidDeviceManager::SocketCallback& callback, |
| 52 int result, |
| 53 net::StreamSocket* socket) { |
| 54 response_message_loop->PostTask(FROM_HERE, |
| 55 base::Bind(callback, result, socket)); |
| 56 } |
| 57 |
27 class HttpRequest { | 58 class HttpRequest { |
28 public: | 59 public: |
29 typedef AndroidDeviceManager::CommandCallback CommandCallback; | 60 typedef AndroidDeviceManager::CommandCallback CommandCallback; |
30 typedef AndroidDeviceManager::SocketCallback SocketCallback; | 61 typedef AndroidDeviceManager::SocketCallback SocketCallback; |
31 | 62 |
32 static void CommandRequest(const std::string& request, | 63 static void CommandRequest(const std::string& request, |
33 const CommandCallback& callback, | 64 const CommandCallback& callback, |
34 int result, | 65 int result, |
35 net::StreamSocket* socket) { | 66 net::StreamSocket* socket) { |
36 if (result != net::OK) { | 67 if (result != net::OK) { |
37 callback.Run(result, std::string()); | 68 callback.Run(result, std::string()); |
38 return; | 69 return; |
39 } | 70 } |
40 new HttpRequest(socket, request, callback); | 71 new HttpRequest(socket, request, callback); |
41 } | 72 } |
42 | 73 |
43 static void SocketRequest(const std::string& request, | 74 static void SocketRequest(const std::string& request, |
44 const SocketCallback& callback, | 75 const SocketCallback& callback, |
45 int result, | 76 int result, |
46 net::StreamSocket* socket) { | 77 net::StreamSocket* socket) { |
47 if (result != net::OK) { | 78 if (result != net::OK) { |
48 callback.Run(result, NULL); | 79 callback.Run(result, NULL); |
49 return; | 80 return; |
50 } | 81 } |
51 new HttpRequest(socket, request, callback); | 82 new HttpRequest(socket, request, callback); |
52 } | 83 } |
53 | 84 |
54 private: | 85 private: |
55 HttpRequest(net::StreamSocket* socket, | 86 HttpRequest(net::StreamSocket* socket, |
56 const std::string& request, | 87 const std::string& request, |
57 const CommandCallback& callback) | 88 const CommandCallback& callback) |
58 : socket_(socket), | 89 : socket_(socket), command_callback_(callback), body_pos_(0) { |
59 command_callback_(callback), | |
60 body_pos_(0) { | |
61 SendRequest(request); | 90 SendRequest(request); |
62 } | 91 } |
63 | 92 |
64 HttpRequest(net::StreamSocket* socket, | 93 HttpRequest(net::StreamSocket* socket, |
65 const std::string& request, | 94 const std::string& request, |
66 const SocketCallback& callback) | 95 const SocketCallback& callback) |
67 : socket_(socket), | 96 : socket_(socket), |
68 socket_callback_(callback), | 97 socket_callback_(callback), |
69 body_pos_(0) { | 98 body_pos_(0) { |
70 SendRequest(request); | 99 SendRequest(request); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 return false; | 196 return false; |
168 } | 197 } |
169 | 198 |
170 scoped_ptr<net::StreamSocket> socket_; | 199 scoped_ptr<net::StreamSocket> socket_; |
171 std::string response_; | 200 std::string response_; |
172 AndroidDeviceManager::CommandCallback command_callback_; | 201 AndroidDeviceManager::CommandCallback command_callback_; |
173 AndroidDeviceManager::SocketCallback socket_callback_; | 202 AndroidDeviceManager::SocketCallback socket_callback_; |
174 size_t body_pos_; | 203 size_t body_pos_; |
175 }; | 204 }; |
176 | 205 |
| 206 class DevicesRequest : public base::RefCountedThreadSafe<DevicesRequest> { |
| 207 public: |
| 208 typedef AndroidDeviceManager::DeviceInfo DeviceInfo; |
| 209 typedef AndroidDeviceManager::DeviceProvider DeviceProvider; |
| 210 typedef AndroidDeviceManager::DeviceProviders DeviceProviders; |
| 211 typedef AndroidDeviceManager::DeviceDescriptors DeviceDescriptors; |
| 212 typedef base::Callback<void(DeviceDescriptors*)> |
| 213 DescriptorsCallback; |
| 214 |
| 215 static void Start(scoped_refptr<base::MessageLoopProxy> device_message_loop, |
| 216 const DeviceProviders& providers, |
| 217 const DescriptorsCallback& callback) { |
| 218 // Don't keep counted reference on calling thread; |
| 219 DevicesRequest* request = new DevicesRequest(callback); |
| 220 // Avoid destruction while sending requests |
| 221 request->AddRef(); |
| 222 for (DeviceProviders::const_iterator it = providers.begin(); |
| 223 it != providers.end(); ++it) { |
| 224 device_message_loop->PostTask( |
| 225 FROM_HERE, |
| 226 base::Bind( |
| 227 &DeviceProvider::QueryDevices, |
| 228 *it, |
| 229 base::Bind(&DevicesRequest::ProcessSerials, request, *it))); |
| 230 } |
| 231 device_message_loop->ReleaseSoon(FROM_HERE, request); |
| 232 } |
| 233 |
| 234 private: |
| 235 explicit DevicesRequest(const DescriptorsCallback& callback) |
| 236 : response_message_loop_(base::MessageLoopProxy::current()), |
| 237 callback_(callback), |
| 238 descriptors_(new DeviceDescriptors()) { |
| 239 } |
| 240 |
| 241 friend class base::RefCountedThreadSafe<DevicesRequest>; |
| 242 ~DevicesRequest() { |
| 243 response_message_loop_->PostTask(FROM_HERE, |
| 244 base::Bind(callback_, descriptors_.release())); |
| 245 } |
| 246 |
| 247 typedef std::vector<std::string> Serials; |
| 248 |
| 249 void ProcessSerials(scoped_refptr<DeviceProvider> provider, |
| 250 const Serials& serials) { |
| 251 for (Serials::const_iterator it = serials.begin(); it != serials.end(); |
| 252 ++it) { |
| 253 descriptors_->resize(descriptors_->size() + 1); |
| 254 descriptors_->back().provider = provider; |
| 255 descriptors_->back().serial = *it; |
| 256 } |
| 257 } |
| 258 |
| 259 scoped_refptr<base::MessageLoopProxy> response_message_loop_; |
| 260 DescriptorsCallback callback_; |
| 261 scoped_ptr<DeviceDescriptors> descriptors_; |
| 262 }; |
| 263 |
| 264 void ReleaseDeviceAndProvider( |
| 265 AndroidDeviceManager::DeviceProvider* provider, |
| 266 const std::string& serial) { |
| 267 provider->ReleaseDevice(serial); |
| 268 provider->Release(); |
| 269 } |
| 270 |
177 } // namespace | 271 } // namespace |
178 | 272 |
179 AndroidDeviceManager::BrowserInfo::BrowserInfo() | 273 AndroidDeviceManager::BrowserInfo::BrowserInfo() |
180 : type(kTypeOther) { | 274 : type(kTypeOther) { |
181 } | 275 } |
182 | 276 |
183 AndroidDeviceManager::DeviceInfo::DeviceInfo() { | 277 AndroidDeviceManager::DeviceInfo::DeviceInfo() |
| 278 : model(kModelOffline), connected(false) { |
184 } | 279 } |
185 | 280 |
186 AndroidDeviceManager::DeviceInfo::~DeviceInfo() { | 281 AndroidDeviceManager::DeviceInfo::~DeviceInfo() { |
187 } | 282 } |
188 | 283 |
189 AndroidDeviceManager::Device::Device(const std::string& serial, | 284 AndroidDeviceManager::DeviceDescriptor::DeviceDescriptor() { |
190 bool is_connected) | |
191 : serial_(serial), | |
192 is_connected_(is_connected) { | |
193 } | 285 } |
194 | 286 |
195 void AndroidDeviceManager::Device::HttpQuery(const std::string& socket_name, | 287 AndroidDeviceManager::DeviceDescriptor::~DeviceDescriptor() { |
196 const std::string& path, | |
197 const CommandCallback& callback) { | |
198 std::string request(base::StringPrintf(kHttpGetRequest, path.c_str())); | |
199 OpenSocket(socket_name, | |
200 base::Bind(&HttpRequest::CommandRequest, request, callback)); | |
201 } | 288 } |
202 | 289 |
203 AndroidDeviceManager::Device::~Device() { | 290 void AndroidDeviceManager::DeviceProvider::SendJsonRequest( |
| 291 const std::string& serial, |
| 292 const std::string& socket_name, |
| 293 const std::string& request, |
| 294 const CommandCallback& callback) { |
| 295 OpenSocket(serial, |
| 296 socket_name, |
| 297 base::Bind(&HttpRequest::CommandRequest, |
| 298 base::StringPrintf(kHttpGetRequest, request.c_str()), |
| 299 callback)); |
| 300 } |
| 301 |
| 302 void AndroidDeviceManager::DeviceProvider::HttpUpgrade( |
| 303 const std::string& serial, |
| 304 const std::string& socket_name, |
| 305 const std::string& url, |
| 306 const SocketCallback& callback) { |
| 307 OpenSocket( |
| 308 serial, |
| 309 socket_name, |
| 310 base::Bind(&HttpRequest::SocketRequest, |
| 311 base::StringPrintf(kWebSocketUpgradeRequest, url.c_str()), |
| 312 callback)); |
| 313 } |
| 314 |
| 315 void AndroidDeviceManager::DeviceProvider::ReleaseDevice( |
| 316 const std::string& serial) { |
204 } | 317 } |
205 | 318 |
206 AndroidDeviceManager::DeviceProvider::DeviceProvider() { | 319 AndroidDeviceManager::DeviceProvider::DeviceProvider() { |
207 } | 320 } |
208 | 321 |
209 AndroidDeviceManager::DeviceProvider::~DeviceProvider() { | 322 AndroidDeviceManager::DeviceProvider::~DeviceProvider() { |
210 } | 323 } |
211 | 324 |
| 325 void AndroidDeviceManager::Device::QueryDeviceInfo( |
| 326 const DeviceInfoCallback& callback) { |
| 327 device_message_loop_->PostTask( |
| 328 FROM_HERE, |
| 329 base::Bind(&DeviceProvider::QueryDeviceInfo, |
| 330 provider_, |
| 331 serial_, |
| 332 base::Bind(&PostDeviceInfoCallback, |
| 333 base::MessageLoopProxy::current(), |
| 334 callback))); |
| 335 } |
| 336 |
| 337 void AndroidDeviceManager::Device::OpenSocket(const std::string& socket_name, |
| 338 const SocketCallback& callback) { |
| 339 device_message_loop_->PostTask( |
| 340 FROM_HERE, |
| 341 base::Bind(&DeviceProvider::OpenSocket, |
| 342 provider_, |
| 343 serial_, |
| 344 socket_name, |
| 345 callback)); |
| 346 } |
| 347 |
| 348 void AndroidDeviceManager::Device::SendJsonRequest( |
| 349 const std::string& socket_name, |
| 350 const std::string& request, |
| 351 const CommandCallback& callback) { |
| 352 device_message_loop_->PostTask( |
| 353 FROM_HERE, |
| 354 base::Bind(&DeviceProvider::SendJsonRequest, |
| 355 provider_, |
| 356 serial_, |
| 357 socket_name, |
| 358 request, |
| 359 base::Bind(&PostCommandCallback, |
| 360 base::MessageLoopProxy::current(), |
| 361 callback))); |
| 362 } |
| 363 |
| 364 void AndroidDeviceManager::Device::HttpUpgrade(const std::string& socket_name, |
| 365 const std::string& url, |
| 366 const SocketCallback& callback) { |
| 367 device_message_loop_->PostTask( |
| 368 FROM_HERE, |
| 369 base::Bind(&DeviceProvider::HttpUpgrade, |
| 370 provider_, |
| 371 serial_, |
| 372 socket_name, |
| 373 url, |
| 374 base::Bind(&PostSocketCallback, |
| 375 base::MessageLoopProxy::current(), |
| 376 callback))); |
| 377 } |
| 378 |
| 379 AndroidDeviceManager::Device::Device( |
| 380 scoped_refptr<base::MessageLoopProxy> device_message_loop, |
| 381 scoped_refptr<DeviceProvider> provider, |
| 382 const std::string& serial) |
| 383 : device_message_loop_(device_message_loop), |
| 384 provider_(provider), |
| 385 serial_(serial), |
| 386 weak_factory_(this) { |
| 387 } |
| 388 |
| 389 AndroidDeviceManager::Device::~Device() { |
| 390 provider_->AddRef(); |
| 391 DeviceProvider* raw_ptr = provider_.get(); |
| 392 provider_ = NULL; |
| 393 device_message_loop_->PostTask( |
| 394 FROM_HERE, |
| 395 base::Bind(&ReleaseDeviceAndProvider, |
| 396 base::Unretained(raw_ptr), |
| 397 serial_)); |
| 398 } |
| 399 |
| 400 AndroidDeviceManager::HandlerThread* |
| 401 AndroidDeviceManager::HandlerThread::instance_ = NULL; |
| 402 |
| 403 // static |
| 404 scoped_refptr<AndroidDeviceManager::HandlerThread> |
| 405 AndroidDeviceManager::HandlerThread::GetInstance() { |
| 406 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 407 if (!instance_) |
| 408 new HandlerThread(); |
| 409 return instance_; |
| 410 } |
| 411 |
| 412 AndroidDeviceManager::HandlerThread::HandlerThread() { |
| 413 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 414 instance_ = this; |
| 415 thread_ = new base::Thread(kDevToolsAdbBridgeThreadName); |
| 416 base::Thread::Options options; |
| 417 options.message_loop_type = base::MessageLoop::TYPE_IO; |
| 418 if (!thread_->StartWithOptions(options)) { |
| 419 delete thread_; |
| 420 thread_ = NULL; |
| 421 } |
| 422 } |
| 423 |
| 424 scoped_refptr<base::MessageLoopProxy> |
| 425 AndroidDeviceManager::HandlerThread::message_loop() { |
| 426 return thread_ ? thread_->message_loop_proxy() : NULL; |
| 427 } |
| 428 |
| 429 // static |
| 430 void AndroidDeviceManager::HandlerThread::StopThread( |
| 431 base::Thread* thread) { |
| 432 thread->Stop(); |
| 433 } |
| 434 |
| 435 AndroidDeviceManager::HandlerThread::~HandlerThread() { |
| 436 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 437 instance_ = NULL; |
| 438 if (!thread_) |
| 439 return; |
| 440 // Shut down thread on FILE thread to join into IO. |
| 441 content::BrowserThread::PostTask( |
| 442 content::BrowserThread::FILE, FROM_HERE, |
| 443 base::Bind(&HandlerThread::StopThread, thread_)); |
| 444 } |
| 445 |
212 // static | 446 // static |
213 scoped_refptr<AndroidDeviceManager> AndroidDeviceManager::Create() { | 447 scoped_refptr<AndroidDeviceManager> AndroidDeviceManager::Create() { |
214 return new AndroidDeviceManager(); | 448 return new AndroidDeviceManager(); |
215 } | 449 } |
216 | 450 |
217 void AndroidDeviceManager::QueryDevices( | 451 void AndroidDeviceManager::SetDeviceProviders( |
218 const DeviceProviders& providers, | 452 const DeviceProviders& providers) { |
219 const QueryDevicesCallback& callback) { | 453 for (DeviceProviders::iterator it = providers_.begin(); |
220 DCHECK(CalledOnValidThread()); | 454 it != providers_.end(); ++it) { |
221 stopped_ = false; | 455 (*it)->AddRef(); |
222 Devices empty; | 456 DeviceProvider* raw_ptr = it->get(); |
223 QueryNextProvider(callback, providers, empty, empty); | 457 *it = NULL; |
| 458 handler_thread_->message_loop()->ReleaseSoon(FROM_HERE, raw_ptr); |
| 459 } |
| 460 providers_ = providers; |
224 } | 461 } |
225 | 462 |
226 void AndroidDeviceManager::Stop() { | 463 void AndroidDeviceManager::QueryDevices(const DevicesCallback& callback) { |
227 DCHECK(CalledOnValidThread()); | 464 DevicesRequest::Start(handler_thread_->message_loop(), |
228 stopped_ = true; | 465 providers_, |
229 devices_.clear(); | 466 base::Bind(&AndroidDeviceManager::UpdateDevices, |
230 } | 467 this, |
231 | 468 callback)); |
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 } | 469 } |
290 | 470 |
291 AndroidDeviceManager::AndroidDeviceManager() | 471 AndroidDeviceManager::AndroidDeviceManager() |
292 : stopped_(false) { | 472 : handler_thread_(HandlerThread::GetInstance()) { |
293 } | 473 } |
294 | 474 |
295 AndroidDeviceManager::~AndroidDeviceManager() { | 475 AndroidDeviceManager::~AndroidDeviceManager() { |
| 476 SetDeviceProviders(DeviceProviders()); |
296 } | 477 } |
297 | 478 |
298 void AndroidDeviceManager::QueryNextProvider( | 479 void AndroidDeviceManager::UpdateDevices( |
299 const QueryDevicesCallback& callback, | 480 const DevicesCallback& callback, |
300 const DeviceProviders& providers, | 481 DeviceDescriptors* descriptors_raw) { |
301 const Devices& total_devices, | 482 scoped_ptr<DeviceDescriptors> descriptors(descriptors_raw); |
302 const Devices& new_devices) { | 483 Devices response; |
303 DCHECK(CalledOnValidThread()); | 484 DeviceWeakMap new_devices; |
304 | 485 for (DeviceDescriptors::const_iterator it = descriptors->begin(); |
305 if (stopped_) | 486 it != descriptors->end(); |
306 return; | 487 ++it) { |
307 | 488 DeviceWeakMap::iterator found = devices_.find(it->serial); |
308 Devices more_devices(total_devices); | 489 scoped_refptr<Device> device; |
309 more_devices.insert( | 490 if (found == devices_.end() || !found->second |
310 more_devices.end(), new_devices.begin(), new_devices.end()); | 491 || found->second->provider_ != it->provider) { |
311 | 492 device = new Device(handler_thread_->message_loop(), |
312 if (providers.empty()) { | 493 it->provider, it->serial); |
313 std::vector<std::string> serials; | 494 } else { |
314 devices_.clear(); | 495 device = found->second.get(); |
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 } | 496 } |
320 callback.Run(serials); | 497 response.push_back(device); |
321 return; | 498 new_devices[it->serial] = device->weak_factory_.GetWeakPtr(); |
322 } | 499 } |
323 | 500 devices_.swap(new_devices); |
324 scoped_refptr<DeviceProvider> current_provider = providers.back(); | 501 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 } | 502 } |
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 |