Chromium Code Reviews| 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 |