OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/devtools_adb_bridge.h" | 5 #include "chrome/browser/devtools/devtools_adb_bridge.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/command_line.h" |
12 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
13 #include "base/json/json_reader.h" | 14 #include "base/json/json_reader.h" |
14 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
15 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/memory/singleton.h" |
16 #include "base/message_loop/message_loop_proxy.h" | 18 #include "base/message_loop/message_loop_proxy.h" |
17 #include "base/rand_util.h" | 19 #include "base/rand_util.h" |
18 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
19 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
20 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" |
21 #include "base/threading/thread.h" | 23 #include "base/threading/thread.h" |
22 #include "base/values.h" | 24 #include "base/values.h" |
| 25 #include "chrome/browser/devtools/adb/android_rsa.h" |
23 #include "chrome/browser/devtools/adb/android_usb_device.h" | 26 #include "chrome/browser/devtools/adb/android_usb_device.h" |
24 #include "chrome/browser/devtools/adb_client_socket.h" | 27 #include "chrome/browser/devtools/adb_client_socket.h" |
25 #include "chrome/browser/devtools/devtools_window.h" | 28 #include "chrome/browser/devtools/devtools_window.h" |
26 #include "chrome/browser/devtools/tethering_adb_filter.h" | 29 #include "chrome/browser/devtools/tethering_adb_filter.h" |
27 #include "chrome/browser/profiles/profile.h" | 30 #include "chrome/browser/profiles/profile.h" |
| 31 #include "chrome/common/chrome_switches.h" |
| 32 #include "components/browser_context_keyed_service/browser_context_dependency_ma
nager.h" |
28 #include "content/public/browser/browser_thread.h" | 33 #include "content/public/browser/browser_thread.h" |
29 #include "content/public/browser/devtools_agent_host.h" | 34 #include "content/public/browser/devtools_agent_host.h" |
30 #include "content/public/browser/devtools_client_host.h" | 35 #include "content/public/browser/devtools_client_host.h" |
31 #include "content/public/browser/devtools_external_agent_proxy.h" | 36 #include "content/public/browser/devtools_external_agent_proxy.h" |
32 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" | 37 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" |
33 #include "content/public/browser/devtools_manager.h" | 38 #include "content/public/browser/devtools_manager.h" |
| 39 #include "crypto/rsa_private_key.h" |
34 #include "net/base/net_errors.h" | 40 #include "net/base/net_errors.h" |
35 #include "net/server/web_socket.h" | 41 #include "net/server/web_socket.h" |
36 | 42 |
37 using content::BrowserThread; | 43 using content::BrowserThread; |
38 using net::WebSocket; | 44 using net::WebSocket; |
39 | 45 |
40 namespace { | 46 namespace { |
41 | 47 |
42 static const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread"; | 48 static const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread"; |
43 static const char kHostDevicesCommand[] = "host:devices"; | 49 static const char kHostDevicesCommand[] = "host:devices"; |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 } | 184 } |
179 | 185 |
180 void Respond(int result, const std::string& response) { | 186 void Respond(int result, const std::string& response) { |
181 callback_.Run(result, response); | 187 callback_.Run(result, response); |
182 } | 188 } |
183 | 189 |
184 std::string query_; | 190 std::string query_; |
185 Callback callback_; | 191 Callback callback_; |
186 }; | 192 }; |
187 | 193 |
188 static void ReceivedDevices(const AndroidDevicesCallback& callback, | |
189 Profile* profile, | |
190 int result, | |
191 const std::string& response) { | |
192 AndroidDevices devices; | |
193 #if defined(DEBUG_DEVTOOLS) | |
194 devices.push_back(new AdbDeviceImpl("")); // For desktop remote debugging. | |
195 std::vector<scoped_refptr<AndroidUsbDevice> > usb_devices; | |
196 AndroidUsbDevice::Enumerate(profile, &usb_devices); | |
197 for (size_t i = 0; i < usb_devices.size(); ++i) | |
198 devices.push_back(new UsbDeviceImpl(usb_devices[i])); | |
199 #endif // defined(DEBUG_DEVTOOLS) | |
200 if (result != net::OK) { | |
201 callback.Run(devices); | |
202 return; | |
203 } | |
204 | |
205 std::vector<std::string> serials; | |
206 Tokenize(response, "\n", &serials); | |
207 for (size_t i = 0; i < serials.size(); ++i) { | |
208 std::vector<std::string> tokens; | |
209 Tokenize(serials[i], "\t ", &tokens); | |
210 devices.push_back(new AdbDeviceImpl(tokens[0])); | |
211 } | |
212 callback.Run(devices); | |
213 } | |
214 | |
215 static void EnumerateDevices(Profile* profile, | |
216 const AndroidDevicesCallback& callback) { | |
217 AdbClientSocket::AdbQuery( | |
218 kAdbPort, kHostDevicesCommand, | |
219 base::Bind(&ReceivedDevices, callback, profile)); | |
220 } | |
221 | |
222 class AdbPagesCommand : public base::RefCounted<AdbPagesCommand> { | 194 class AdbPagesCommand : public base::RefCounted<AdbPagesCommand> { |
223 public: | 195 public: |
224 explicit AdbPagesCommand(const PagesCallback& callback) | 196 explicit AdbPagesCommand(DevToolsAdbBridge* bridge, |
225 : callback_(callback) { | 197 const PagesCallback& callback) |
| 198 : bridge_(bridge), |
| 199 callback_(callback) { |
226 pages_.reset(new DevToolsAdbBridge::RemotePages()); | 200 pages_.reset(new DevToolsAdbBridge::RemotePages()); |
227 } | 201 } |
228 | 202 |
229 void Run(Profile* profile) { | 203 void Run() { |
230 EnumerateDevices(profile, | 204 bridge_->EnumerateDevices(base::Bind(&AdbPagesCommand::ReceivedDevices, |
231 base::Bind(&AdbPagesCommand::ReceivedDevices, this)); | 205 this)); |
232 } | 206 } |
233 | 207 |
234 private: | 208 private: |
235 friend class base::RefCounted<AdbPagesCommand>; | 209 friend class base::RefCounted<AdbPagesCommand>; |
236 virtual ~AdbPagesCommand() {} | 210 virtual ~AdbPagesCommand() {} |
237 | 211 |
238 void ReceivedDevices(const AndroidDevices& devices) { | 212 void ReceivedDevices(const AndroidDevices& devices) { |
239 devices_ = devices; | 213 devices_ = devices; |
240 ProcessSerials(); | 214 ProcessSerials(); |
241 } | 215 } |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 std::string package = path_field.substr(1, socket_name_pos - 2); | 377 std::string package = path_field.substr(1, socket_name_pos - 2); |
404 if (socket_name_pos + channel_pattern.size() < path_field.size() - 1) { | 378 if (socket_name_pos + channel_pattern.size() < path_field.size() - 1) { |
405 package += path_field.substr( | 379 package += path_field.substr( |
406 socket_name_pos + channel_pattern.size(), path_field.size() - 1); | 380 socket_name_pos + channel_pattern.size(), path_field.size() - 1); |
407 } | 381 } |
408 package[0] = base::ToUpperASCII(package[0]); | 382 package[0] = base::ToUpperASCII(package[0]); |
409 socket_to_package_[socket] = package; | 383 socket_to_package_[socket] = package; |
410 } | 384 } |
411 } | 385 } |
412 | 386 |
| 387 scoped_refptr<DevToolsAdbBridge> bridge_; |
413 PagesCallback callback_; | 388 PagesCallback callback_; |
414 AndroidDevices devices_; | 389 AndroidDevices devices_; |
415 std::vector<std::string> sockets_; | 390 std::vector<std::string> sockets_; |
416 std::map<std::string, std::string> socket_to_package_; | 391 std::map<std::string, std::string> socket_to_package_; |
417 scoped_ptr<DevToolsAdbBridge::RemotePages> pages_; | 392 scoped_ptr<DevToolsAdbBridge::RemotePages> pages_; |
418 }; | 393 }; |
419 | 394 |
420 } // namespace | 395 } // namespace |
421 | 396 |
422 const char kDevToolsChannelNameFormat[] = "%s_devtools_remote"; | 397 const char kDevToolsChannelNameFormat[] = "%s_devtools_remote"; |
423 | 398 |
424 class AgentHostDelegate; | 399 class AgentHostDelegate; |
425 | 400 |
426 typedef std::map<std::string, AgentHostDelegate*> AgentHostDelegates; | 401 typedef std::map<std::string, AgentHostDelegate*> AgentHostDelegates; |
427 | 402 |
428 base::LazyInstance<AgentHostDelegates>::Leaky g_host_delegates = | 403 base::LazyInstance<AgentHostDelegates>::Leaky g_host_delegates = |
429 LAZY_INSTANCE_INITIALIZER; | 404 LAZY_INSTANCE_INITIALIZER; |
430 | 405 |
| 406 DevToolsAdbBridge::Wrapper::Wrapper(Profile* profile) |
| 407 : bridge_(new DevToolsAdbBridge(profile)) { |
| 408 } |
| 409 |
| 410 DevToolsAdbBridge::Wrapper::~Wrapper() { |
| 411 } |
| 412 |
| 413 DevToolsAdbBridge* DevToolsAdbBridge::Wrapper::Get() { |
| 414 return bridge_.get(); |
| 415 } |
| 416 |
| 417 // static |
| 418 DevToolsAdbBridge::Factory* DevToolsAdbBridge::Factory::GetInstance() { |
| 419 return Singleton<DevToolsAdbBridge::Factory>::get(); |
| 420 } |
| 421 |
| 422 // static |
| 423 DevToolsAdbBridge* DevToolsAdbBridge::Factory::GetForProfile( |
| 424 Profile* profile) { |
| 425 return static_cast<DevToolsAdbBridge::Wrapper*>( |
| 426 GetInstance()->GetServiceForBrowserContext(profile, true))->Get(); |
| 427 } |
| 428 |
| 429 DevToolsAdbBridge::Factory::Factory() |
| 430 : BrowserContextKeyedServiceFactory( |
| 431 "DevToolsAdbBridge", |
| 432 BrowserContextDependencyManager::GetInstance()) {} |
| 433 |
| 434 DevToolsAdbBridge::Factory::~Factory() {} |
| 435 |
| 436 BrowserContextKeyedService* |
| 437 DevToolsAdbBridge::Factory::BuildServiceInstanceFor( |
| 438 content::BrowserContext* context) const { |
| 439 return new DevToolsAdbBridge::Wrapper(Profile::FromBrowserContext(context)); |
| 440 } |
| 441 |
431 DevToolsAdbBridge::AndroidDevice::AndroidDevice(const std::string& serial) | 442 DevToolsAdbBridge::AndroidDevice::AndroidDevice(const std::string& serial) |
432 : serial_(serial) { | 443 : serial_(serial) { |
433 } | 444 } |
434 | 445 |
435 void DevToolsAdbBridge::AndroidDevice::HttpQuery( | 446 void DevToolsAdbBridge::AndroidDevice::HttpQuery( |
436 const std::string& la_name, | 447 const std::string& la_name, |
437 const std::string& request, | 448 const std::string& request, |
438 const CommandCallback& callback) { | 449 const CommandCallback& callback) { |
439 OpenSocket(la_name, base::Bind(&AndroidDevice::OnHttpSocketOpened, this, | 450 OpenSocket(la_name, base::Bind(&AndroidDevice::OnHttpSocketOpened, this, |
440 request, callback)); | 451 request, callback)); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 scoped_refptr<DevToolsAdbBridge::RefCountedAdbThread> adb_thread_; | 640 scoped_refptr<DevToolsAdbBridge::RefCountedAdbThread> adb_thread_; |
630 scoped_ptr<net::StreamSocket> socket_; | 641 scoped_ptr<net::StreamSocket> socket_; |
631 scoped_ptr<content::DevToolsExternalAgentProxy> proxy_; | 642 scoped_ptr<content::DevToolsExternalAgentProxy> proxy_; |
632 std::string response_buffer_; | 643 std::string response_buffer_; |
633 TetheringAdbFilter tethering_adb_filter_; | 644 TetheringAdbFilter tethering_adb_filter_; |
634 DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate); | 645 DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate); |
635 }; | 646 }; |
636 | 647 |
637 class AdbAttachCommand : public base::RefCounted<AdbAttachCommand> { | 648 class AdbAttachCommand : public base::RefCounted<AdbAttachCommand> { |
638 public: | 649 public: |
639 AdbAttachCommand(const base::WeakPtr<DevToolsAdbBridge>& bridge, | 650 AdbAttachCommand(DevToolsAdbBridge* bridge, |
640 const std::string& serial, | 651 const std::string& serial, |
641 const std::string& socket, | 652 const std::string& socket, |
642 const std::string& debug_url, | 653 const std::string& debug_url, |
643 const std::string& frontend_url) | 654 const std::string& frontend_url) |
644 : bridge_(bridge), | 655 : bridge_(bridge), |
645 serial_(serial), | 656 serial_(serial), |
646 socket_(socket), | 657 socket_(socket), |
647 debug_url_(debug_url), | 658 debug_url_(debug_url), |
648 frontend_url_(frontend_url) { | 659 frontend_url_(frontend_url) { |
649 } | 660 } |
650 | 661 |
651 void Run(Profile* profile) { | 662 void Run() { |
652 | 663 bridge_->EnumerateDevices(base::Bind(&AdbAttachCommand::ReceivedDevices, |
653 // scoped_refptr<DevToolsAdbBridge::AndroidDevice> device = | |
654 // new AdbDeviceImpl(serial_); | |
655 | |
656 DevToolsAdbBridge* bridge = bridge_.get(); | |
657 if (!bridge) | |
658 return; | |
659 | |
660 EnumerateDevices(profile, base::Bind(&AdbAttachCommand::ReceivedDevices, | |
661 this)); | 664 this)); |
662 } | 665 } |
663 | 666 |
664 private: | 667 private: |
665 friend class base::RefCounted<AdbAttachCommand>; | 668 friend class base::RefCounted<AdbAttachCommand>; |
666 virtual ~AdbAttachCommand() {} | 669 virtual ~AdbAttachCommand() {} |
667 | 670 |
668 void ReceivedDevices(const AndroidDevices& devices) { | 671 void ReceivedDevices(const AndroidDevices& devices) { |
669 for (AndroidDevices::const_iterator it = devices.begin(); | 672 for (AndroidDevices::const_iterator it = devices.begin(); |
670 it != devices.end(); ++it) { | 673 it != devices.end(); ++it) { |
(...skipping 11 matching lines...) Expand all Loading... |
682 if (result != net::OK || socket == NULL) | 685 if (result != net::OK || socket == NULL) |
683 return; | 686 return; |
684 | 687 |
685 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 688 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
686 base::Bind(&AdbAttachCommand::OpenDevToolsWindow, this, socket)); | 689 base::Bind(&AdbAttachCommand::OpenDevToolsWindow, this, socket)); |
687 } | 690 } |
688 | 691 |
689 void OpenDevToolsWindow(net::StreamSocket* socket) { | 692 void OpenDevToolsWindow(net::StreamSocket* socket) { |
690 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 693 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
691 | 694 |
692 DevToolsAdbBridge* bridge = bridge_.get(); | |
693 if (!bridge) | |
694 return; | |
695 | |
696 std::string id = base::StringPrintf("%s:%s", serial_.c_str(), | 695 std::string id = base::StringPrintf("%s:%s", serial_.c_str(), |
697 debug_url_.c_str()); | 696 debug_url_.c_str()); |
698 AgentHostDelegates::iterator it = g_host_delegates.Get().find(id); | 697 AgentHostDelegates::iterator it = g_host_delegates.Get().find(id); |
699 AgentHostDelegate* delegate; | 698 AgentHostDelegate* delegate; |
700 if (it != g_host_delegates.Get().end()) | 699 if (it != g_host_delegates.Get().end()) |
701 delegate = it->second; | 700 delegate = it->second; |
702 else | 701 else |
703 delegate = new AgentHostDelegate(id, serial_, bridge->adb_thread_, | 702 delegate = new AgentHostDelegate(id, serial_, bridge_->adb_thread_, |
704 socket); | 703 socket); |
705 DevToolsWindow::OpenExternalFrontend( | 704 DevToolsWindow::OpenExternalFrontend( |
706 bridge->profile_, frontend_url_, delegate->GetAgentHost().get()); | 705 bridge_->profile_, frontend_url_, delegate->GetAgentHost().get()); |
707 } | 706 } |
708 | 707 |
709 base::WeakPtr<DevToolsAdbBridge> bridge_; | 708 scoped_refptr<DevToolsAdbBridge> bridge_; |
710 std::string serial_; | 709 std::string serial_; |
711 std::string socket_; | 710 std::string socket_; |
712 std::string debug_url_; | 711 std::string debug_url_; |
713 std::string frontend_url_; | 712 std::string frontend_url_; |
714 }; | 713 }; |
715 | 714 |
716 DevToolsAdbBridge::RemotePage::RemotePage(const std::string& serial, | 715 DevToolsAdbBridge::RemotePage::RemotePage(const std::string& serial, |
717 const std::string& model, | 716 const std::string& model, |
718 const std::string& package, | 717 const std::string& package, |
719 const std::string& socket, | 718 const std::string& socket, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 return; | 783 return; |
785 // Shut down thread on FILE thread to join into IO. | 784 // Shut down thread on FILE thread to join into IO. |
786 BrowserThread::PostTask( | 785 BrowserThread::PostTask( |
787 BrowserThread::FILE, FROM_HERE, | 786 BrowserThread::FILE, FROM_HERE, |
788 base::Bind(&RefCountedAdbThread::StopThread, thread_)); | 787 base::Bind(&RefCountedAdbThread::StopThread, thread_)); |
789 } | 788 } |
790 | 789 |
791 DevToolsAdbBridge::DevToolsAdbBridge(Profile* profile) | 790 DevToolsAdbBridge::DevToolsAdbBridge(Profile* profile) |
792 : profile_(profile), | 791 : profile_(profile), |
793 adb_thread_(RefCountedAdbThread::GetInstance()), | 792 adb_thread_(RefCountedAdbThread::GetInstance()), |
794 weak_factory_(this), | |
795 has_message_loop_(adb_thread_->message_loop() != NULL) { | 793 has_message_loop_(adb_thread_->message_loop() != NULL) { |
| 794 rsa_key_.reset(AndroidRSAPrivateKey(profile)); |
796 } | 795 } |
797 | 796 |
798 DevToolsAdbBridge::~DevToolsAdbBridge() { | 797 void DevToolsAdbBridge::EnumerateDevices( |
799 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 798 const AndroidDevicesCallback& callback) { |
| 799 AdbClientSocket::AdbQuery( |
| 800 kAdbPort, kHostDevicesCommand, |
| 801 base::Bind(&DevToolsAdbBridge::ReceivedDevices, this, callback)); |
800 } | 802 } |
801 | 803 |
802 void DevToolsAdbBridge::Query( | 804 void DevToolsAdbBridge::Query( |
803 const std::string query, | 805 const std::string query, |
804 const Callback& callback) { | 806 const Callback& callback) { |
805 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 807 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
806 if (!has_message_loop_) { | 808 if (!has_message_loop_) { |
807 callback.Run(net::ERR_FAILED, "Could not start ADB thread"); | 809 callback.Run(net::ERR_FAILED, "Could not start ADB thread"); |
808 return; | 810 return; |
809 } | 811 } |
810 scoped_refptr<AdbQueryCommand> command(new AdbQueryCommand(query, callback)); | 812 scoped_refptr<AdbQueryCommand> command(new AdbQueryCommand(query, callback)); |
811 adb_thread_->message_loop()->PostTask(FROM_HERE, | 813 adb_thread_->message_loop()->PostTask(FROM_HERE, |
812 base::Bind(&AdbQueryCommand::Run, command)); | 814 base::Bind(&AdbQueryCommand::Run, command)); |
813 } | 815 } |
814 | 816 |
815 void DevToolsAdbBridge::Pages(const PagesCallback& callback) { | 817 void DevToolsAdbBridge::Pages(const PagesCallback& callback) { |
816 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 818 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
817 if (!has_message_loop_) | 819 if (!has_message_loop_) |
818 return; | 820 return; |
819 | 821 |
820 scoped_refptr<AdbPagesCommand> command( | 822 scoped_refptr<AdbPagesCommand> command( |
821 new AdbPagesCommand(callback)); | 823 new AdbPagesCommand(this, callback)); |
822 adb_thread_->message_loop()->PostTask(FROM_HERE, | 824 adb_thread_->message_loop()->PostTask(FROM_HERE, |
823 base::Bind(&AdbPagesCommand::Run, command, profile_)); | 825 base::Bind(&AdbPagesCommand::Run, command)); |
824 } | 826 } |
825 | 827 |
826 void DevToolsAdbBridge::Attach(const std::string& serial, | 828 void DevToolsAdbBridge::Attach(const std::string& serial, |
827 const std::string& socket, | 829 const std::string& socket, |
828 const std::string& debug_url, | 830 const std::string& debug_url, |
829 const std::string& frontend_url) { | 831 const std::string& frontend_url) { |
830 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 832 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
831 if (!has_message_loop_) | 833 if (!has_message_loop_) |
832 return; | 834 return; |
833 | 835 |
834 scoped_refptr<AdbAttachCommand> command( | 836 scoped_refptr<AdbAttachCommand> command( |
835 new AdbAttachCommand(weak_factory_.GetWeakPtr(), serial, socket, | 837 new AdbAttachCommand(this, serial, socket, |
836 debug_url, frontend_url)); | 838 debug_url, frontend_url)); |
837 adb_thread_->message_loop()->PostTask( | 839 adb_thread_->message_loop()->PostTask( |
838 FROM_HERE, | 840 FROM_HERE, |
839 base::Bind(&AdbAttachCommand::Run, command, profile_)); | 841 base::Bind(&AdbAttachCommand::Run, command)); |
840 } | 842 } |
| 843 |
| 844 DevToolsAdbBridge::~DevToolsAdbBridge() { |
| 845 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 846 } |
| 847 |
| 848 void DevToolsAdbBridge::ReceivedDevices(const AndroidDevicesCallback& callback, |
| 849 int result, |
| 850 const std::string& response) { |
| 851 AndroidDevices devices; |
| 852 #if defined(DEBUG_DEVTOOLS) |
| 853 devices.push_back(new AdbDeviceImpl("")); // For desktop remote debugging. |
| 854 #endif // defined(DEBUG_DEVTOOLS) |
| 855 |
| 856 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 857 switches::kRemoteDebuggingRawUSB)) { |
| 858 AndroidUsbDevices usb_devices; |
| 859 AndroidUsbDevice::Enumerate(profile_, rsa_key_.get(), &usb_devices); |
| 860 for (AndroidUsbDevices::iterator it = usb_devices.begin(); |
| 861 it != usb_devices.end(); ++it) { |
| 862 devices.push_back(new UsbDeviceImpl(*it)); |
| 863 } |
| 864 } |
| 865 |
| 866 if (result != net::OK) { |
| 867 callback.Run(devices); |
| 868 return; |
| 869 } |
| 870 |
| 871 std::vector<std::string> serials; |
| 872 Tokenize(response, "\n", &serials); |
| 873 for (size_t i = 0; i < serials.size(); ++i) { |
| 874 std::vector<std::string> tokens; |
| 875 Tokenize(serials[i], "\t ", &tokens); |
| 876 devices.push_back(new AdbDeviceImpl(tokens[0])); |
| 877 } |
| 878 callback.Run(devices); |
| 879 } |
OLD | NEW |