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/browser/ui/app_list/search/history.h" | |
32 #include "chrome/common/chrome_switches.h" | |
33 #include "crypto/rsa_private_key.h" | |
34 #include "components/browser_context_keyed_service/browser_context_dependency_ma nager.h" | |
28 #include "content/public/browser/browser_thread.h" | 35 #include "content/public/browser/browser_thread.h" |
29 #include "content/public/browser/devtools_agent_host.h" | 36 #include "content/public/browser/devtools_agent_host.h" |
30 #include "content/public/browser/devtools_client_host.h" | 37 #include "content/public/browser/devtools_client_host.h" |
31 #include "content/public/browser/devtools_external_agent_proxy.h" | 38 #include "content/public/browser/devtools_external_agent_proxy.h" |
32 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" | 39 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" |
33 #include "content/public/browser/devtools_manager.h" | 40 #include "content/public/browser/devtools_manager.h" |
34 #include "net/base/net_errors.h" | 41 #include "net/base/net_errors.h" |
35 #include "net/server/web_socket.h" | 42 #include "net/server/web_socket.h" |
36 | 43 |
37 using content::BrowserThread; | 44 using content::BrowserThread; |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
178 } | 185 } |
179 | 186 |
180 void Respond(int result, const std::string& response) { | 187 void Respond(int result, const std::string& response) { |
181 callback_.Run(result, response); | 188 callback_.Run(result, response); |
182 } | 189 } |
183 | 190 |
184 std::string query_; | 191 std::string query_; |
185 Callback callback_; | 192 Callback callback_; |
186 }; | 193 }; |
187 | 194 |
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> { | 195 class AdbPagesCommand : public base::RefCounted<AdbPagesCommand> { |
223 public: | 196 public: |
224 explicit AdbPagesCommand(const PagesCallback& callback) | 197 explicit AdbPagesCommand(const base::WeakPtr<DevToolsAdbBridge>& bridge, |
vsevik
2013/07/11 15:59:54
Use raw pointer from now on.
pfeldman
2013/07/11 16:26:51
Fooled you here - I can't do this since the comman
| |
225 : callback_(callback) { | 198 const PagesCallback& callback) |
199 : bridge_(bridge), | |
200 callback_(callback) { | |
226 pages_.reset(new DevToolsAdbBridge::RemotePages()); | 201 pages_.reset(new DevToolsAdbBridge::RemotePages()); |
227 } | 202 } |
228 | 203 |
229 void Run(Profile* profile) { | 204 void Run() { |
230 EnumerateDevices(profile, | 205 DevToolsAdbBridge* bridge = bridge_.get(); |
231 base::Bind(&AdbPagesCommand::ReceivedDevices, this)); | 206 if (!bridge) { |
207 BrowserThread::PostTask( | |
208 BrowserThread::UI, FROM_HERE, | |
209 base::Bind(&AdbPagesCommand::Respond, this)); | |
210 return; | |
211 } | |
212 bridge->EnumerateDevices(base::Bind(&AdbPagesCommand::ReceivedDevices, | |
213 this)); | |
232 } | 214 } |
233 | 215 |
234 private: | 216 private: |
235 friend class base::RefCounted<AdbPagesCommand>; | 217 friend class base::RefCounted<AdbPagesCommand>; |
236 virtual ~AdbPagesCommand() {} | 218 virtual ~AdbPagesCommand() {} |
237 | 219 |
238 void ReceivedDevices(const AndroidDevices& devices) { | 220 void ReceivedDevices(const AndroidDevices& devices) { |
239 devices_ = devices; | 221 devices_ = devices; |
240 ProcessSerials(); | 222 ProcessSerials(); |
241 } | 223 } |
(...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); | 385 std::string package = path_field.substr(1, socket_name_pos - 2); |
404 if (socket_name_pos + channel_pattern.size() < path_field.size() - 1) { | 386 if (socket_name_pos + channel_pattern.size() < path_field.size() - 1) { |
405 package += path_field.substr( | 387 package += path_field.substr( |
406 socket_name_pos + channel_pattern.size(), path_field.size() - 1); | 388 socket_name_pos + channel_pattern.size(), path_field.size() - 1); |
407 } | 389 } |
408 package[0] = base::ToUpperASCII(package[0]); | 390 package[0] = base::ToUpperASCII(package[0]); |
409 socket_to_package_[socket] = package; | 391 socket_to_package_[socket] = package; |
410 } | 392 } |
411 } | 393 } |
412 | 394 |
395 base::WeakPtr<DevToolsAdbBridge> bridge_; | |
413 PagesCallback callback_; | 396 PagesCallback callback_; |
414 AndroidDevices devices_; | 397 AndroidDevices devices_; |
415 std::vector<std::string> sockets_; | 398 std::vector<std::string> sockets_; |
416 std::map<std::string, std::string> socket_to_package_; | 399 std::map<std::string, std::string> socket_to_package_; |
417 scoped_ptr<DevToolsAdbBridge::RemotePages> pages_; | 400 scoped_ptr<DevToolsAdbBridge::RemotePages> pages_; |
418 }; | 401 }; |
419 | 402 |
420 } // namespace | 403 } // namespace |
421 | 404 |
422 const char kDevToolsChannelNameFormat[] = "%s_devtools_remote"; | 405 const char kDevToolsChannelNameFormat[] = "%s_devtools_remote"; |
423 | 406 |
424 class AgentHostDelegate; | 407 class AgentHostDelegate; |
425 | 408 |
426 typedef std::map<std::string, AgentHostDelegate*> AgentHostDelegates; | 409 typedef std::map<std::string, AgentHostDelegate*> AgentHostDelegates; |
427 | 410 |
428 base::LazyInstance<AgentHostDelegates>::Leaky g_host_delegates = | 411 base::LazyInstance<AgentHostDelegates>::Leaky g_host_delegates = |
429 LAZY_INSTANCE_INITIALIZER; | 412 LAZY_INSTANCE_INITIALIZER; |
430 | 413 |
414 // static | |
415 DevToolsAdbBridge::Factory* DevToolsAdbBridge::Factory::GetInstance() { | |
416 return Singleton<DevToolsAdbBridge::Factory>::get(); | |
417 } | |
418 | |
419 // static | |
vsevik
2013/07/11 15:59:54
not static
pfeldman
2013/07/11 16:26:51
Oops, it was Ok.
| |
420 DevToolsAdbBridge* DevToolsAdbBridge::Factory::GetForProfile( | |
421 Profile* profile) { | |
422 return static_cast<DevToolsAdbBridge*>( | |
423 GetInstance()->GetServiceForBrowserContext(profile, true)); | |
424 } | |
425 | |
426 DevToolsAdbBridge::Factory::Factory() | |
427 : BrowserContextKeyedServiceFactory( | |
428 "DevToolsAdbBridge", | |
429 BrowserContextDependencyManager::GetInstance()) {} | |
430 | |
431 DevToolsAdbBridge::Factory::~Factory() {} | |
432 | |
433 BrowserContextKeyedService* | |
434 DevToolsAdbBridge::Factory::BuildServiceInstanceFor( | |
435 content::BrowserContext* context) const { | |
436 return new DevToolsAdbBridge(Profile::FromBrowserContext(context)); | |
437 } | |
438 | |
431 DevToolsAdbBridge::AndroidDevice::AndroidDevice(const std::string& serial) | 439 DevToolsAdbBridge::AndroidDevice::AndroidDevice(const std::string& serial) |
432 : serial_(serial) { | 440 : serial_(serial) { |
433 } | 441 } |
434 | 442 |
435 void DevToolsAdbBridge::AndroidDevice::HttpQuery( | 443 void DevToolsAdbBridge::AndroidDevice::HttpQuery( |
436 const std::string& la_name, | 444 const std::string& la_name, |
437 const std::string& request, | 445 const std::string& request, |
438 const CommandCallback& callback) { | 446 const CommandCallback& callback) { |
439 OpenSocket(la_name, base::Bind(&AndroidDevice::OnHttpSocketOpened, this, | 447 OpenSocket(la_name, base::Bind(&AndroidDevice::OnHttpSocketOpened, this, |
440 request, callback)); | 448 request, callback)); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
641 const std::string& socket, | 649 const std::string& socket, |
642 const std::string& debug_url, | 650 const std::string& debug_url, |
643 const std::string& frontend_url) | 651 const std::string& frontend_url) |
644 : bridge_(bridge), | 652 : bridge_(bridge), |
645 serial_(serial), | 653 serial_(serial), |
646 socket_(socket), | 654 socket_(socket), |
647 debug_url_(debug_url), | 655 debug_url_(debug_url), |
648 frontend_url_(frontend_url) { | 656 frontend_url_(frontend_url) { |
649 } | 657 } |
650 | 658 |
651 void Run(Profile* profile) { | 659 void Run() { |
652 | |
653 // scoped_refptr<DevToolsAdbBridge::AndroidDevice> device = | |
654 // new AdbDeviceImpl(serial_); | |
655 | |
656 DevToolsAdbBridge* bridge = bridge_.get(); | 660 DevToolsAdbBridge* bridge = bridge_.get(); |
657 if (!bridge) | 661 if (!bridge) |
658 return; | 662 return; |
659 | 663 bridge_->EnumerateDevices(base::Bind(&AdbAttachCommand::ReceivedDevices, |
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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
786 BrowserThread::PostTask( | 789 BrowserThread::PostTask( |
787 BrowserThread::FILE, FROM_HERE, | 790 BrowserThread::FILE, FROM_HERE, |
788 base::Bind(&RefCountedAdbThread::StopThread, thread_)); | 791 base::Bind(&RefCountedAdbThread::StopThread, thread_)); |
789 } | 792 } |
790 | 793 |
791 DevToolsAdbBridge::DevToolsAdbBridge(Profile* profile) | 794 DevToolsAdbBridge::DevToolsAdbBridge(Profile* profile) |
792 : profile_(profile), | 795 : profile_(profile), |
793 adb_thread_(RefCountedAdbThread::GetInstance()), | 796 adb_thread_(RefCountedAdbThread::GetInstance()), |
794 weak_factory_(this), | 797 weak_factory_(this), |
795 has_message_loop_(adb_thread_->message_loop() != NULL) { | 798 has_message_loop_(adb_thread_->message_loop() != NULL) { |
799 rsa_key_.reset(AndroidRSAPrivateKey(profile)); | |
796 } | 800 } |
797 | 801 |
798 DevToolsAdbBridge::~DevToolsAdbBridge() { | 802 DevToolsAdbBridge::~DevToolsAdbBridge() { |
799 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 803 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
800 } | 804 } |
801 | 805 |
806 void DevToolsAdbBridge::EnumerateDevices( | |
807 const AndroidDevicesCallback& callback) { | |
808 AdbClientSocket::AdbQuery( | |
809 kAdbPort, kHostDevicesCommand, | |
810 base::Bind(&DevToolsAdbBridge::ReceivedDevices, base::Unretained(this), | |
811 callback)); | |
812 } | |
813 | |
802 void DevToolsAdbBridge::Query( | 814 void DevToolsAdbBridge::Query( |
803 const std::string query, | 815 const std::string query, |
804 const Callback& callback) { | 816 const Callback& callback) { |
805 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 817 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
806 if (!has_message_loop_) { | 818 if (!has_message_loop_) { |
807 callback.Run(net::ERR_FAILED, "Could not start ADB thread"); | 819 callback.Run(net::ERR_FAILED, "Could not start ADB thread"); |
808 return; | 820 return; |
809 } | 821 } |
810 scoped_refptr<AdbQueryCommand> command(new AdbQueryCommand(query, callback)); | 822 scoped_refptr<AdbQueryCommand> command(new AdbQueryCommand(query, callback)); |
811 adb_thread_->message_loop()->PostTask(FROM_HERE, | 823 adb_thread_->message_loop()->PostTask(FROM_HERE, |
812 base::Bind(&AdbQueryCommand::Run, command)); | 824 base::Bind(&AdbQueryCommand::Run, command)); |
813 } | 825 } |
814 | 826 |
815 void DevToolsAdbBridge::Pages(const PagesCallback& callback) { | 827 void DevToolsAdbBridge::Pages(const PagesCallback& callback) { |
816 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 828 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
817 if (!has_message_loop_) | 829 if (!has_message_loop_) |
818 return; | 830 return; |
819 | 831 |
820 scoped_refptr<AdbPagesCommand> command( | 832 scoped_refptr<AdbPagesCommand> command( |
821 new AdbPagesCommand(callback)); | 833 new AdbPagesCommand(weak_factory_.GetWeakPtr(), callback)); |
822 adb_thread_->message_loop()->PostTask(FROM_HERE, | 834 adb_thread_->message_loop()->PostTask(FROM_HERE, |
823 base::Bind(&AdbPagesCommand::Run, command, profile_)); | 835 base::Bind(&AdbPagesCommand::Run, command)); |
824 } | 836 } |
825 | 837 |
826 void DevToolsAdbBridge::Attach(const std::string& serial, | 838 void DevToolsAdbBridge::Attach(const std::string& serial, |
827 const std::string& socket, | 839 const std::string& socket, |
828 const std::string& debug_url, | 840 const std::string& debug_url, |
829 const std::string& frontend_url) { | 841 const std::string& frontend_url) { |
830 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 842 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
831 if (!has_message_loop_) | 843 if (!has_message_loop_) |
832 return; | 844 return; |
833 | 845 |
834 scoped_refptr<AdbAttachCommand> command( | 846 scoped_refptr<AdbAttachCommand> command( |
835 new AdbAttachCommand(weak_factory_.GetWeakPtr(), serial, socket, | 847 new AdbAttachCommand(weak_factory_.GetWeakPtr(), serial, socket, |
836 debug_url, frontend_url)); | 848 debug_url, frontend_url)); |
837 adb_thread_->message_loop()->PostTask( | 849 adb_thread_->message_loop()->PostTask( |
838 FROM_HERE, | 850 FROM_HERE, |
839 base::Bind(&AdbAttachCommand::Run, command, profile_)); | 851 base::Bind(&AdbAttachCommand::Run, command)); |
840 } | 852 } |
853 | |
854 void DevToolsAdbBridge::ReceivedDevices(const AndroidDevicesCallback& callback, | |
855 int result, | |
856 const std::string& response) { | |
857 AndroidDevices devices; | |
858 #if defined(DEBUG_DEVTOOLS) | |
859 devices.push_back(new AdbDeviceImpl("")); // For desktop remote debugging. | |
860 #endif // defined(DEBUG_DEVTOOLS) | |
861 | |
862 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
863 switches::kRemoteDebuggingRawUSB)) { | |
864 AndroidUsbDevices usb_devices; | |
865 AndroidUsbDevice::Enumerate(profile_, rsa_key_.get(), &usb_devices); | |
866 for (AndroidUsbDevices::iterator it = usb_devices.begin(); | |
867 it != usb_devices.end(); ++it) { | |
868 devices.push_back(new UsbDeviceImpl(*it)); | |
869 } | |
870 } | |
871 | |
872 if (result != net::OK) { | |
873 callback.Run(devices); | |
874 return; | |
875 } | |
876 | |
877 std::vector<std::string> serials; | |
878 Tokenize(response, "\n", &serials); | |
879 for (size_t i = 0; i < serials.size(); ++i) { | |
880 std::vector<std::string> tokens; | |
881 Tokenize(serials[i], "\t ", &tokens); | |
882 devices.push_back(new AdbDeviceImpl(tokens[0])); | |
883 } | |
884 callback.Run(devices); | |
885 } | |
OLD | NEW |