Chromium Code Reviews| Index: chrome/browser/devtools/devtools_adb_bridge.cc |
| diff --git a/chrome/browser/devtools/devtools_adb_bridge.cc b/chrome/browser/devtools/devtools_adb_bridge.cc |
| index 259578e173df873ea69a138c13150d63c1d9e1e1..56f09b7efda3a3615a1f1be1ca621a6383e091d4 100644 |
| --- a/chrome/browser/devtools/devtools_adb_bridge.cc |
| +++ b/chrome/browser/devtools/devtools_adb_bridge.cc |
| @@ -12,6 +12,7 @@ |
| #include "base/command_line.h" |
| #include "base/compiler_specific.h" |
| #include "base/json/json_reader.h" |
| +#include "base/json/json_writer.h" |
| #include "base/lazy_instance.h" |
| #include "base/logging.h" |
| #include "base/memory/singleton.h" |
| @@ -51,6 +52,8 @@ static const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix"; |
| static const char kPageListRequest[] = "GET /json HTTP/1.1\r\n\r\n"; |
| static const char kVersionRequest[] = "GET /json/version HTTP/1.1\r\n\r\n"; |
| +static const char kClosePageRequest[] = "GET /json/close/%s HTTP/1.1\r\n\r\n"; |
| +static const char kNewPageRequest[] = "GET /json/new HTTP/1.1\r\n\r\n"; |
| const int kAdbPort = 5037; |
| const int kBufferSize = 16 * 1024; |
| const int kAdbPollingIntervalMs = 1000; |
| @@ -384,6 +387,74 @@ class AdbPagesCommand : public base::RefCountedThreadSafe< |
| scoped_ptr<DevToolsAdbBridge::RemoteDevices> remote_devices_; |
| }; |
| +class AdbRemotePageCommand : public base::RefCountedThreadSafe< |
|
pfeldman
2013/08/06 13:33:34
Wat?
Vladislav Kaznacheev
2013/08/07 09:35:12
Replaced with a bind
On 2013/08/06 13:33:34, pfeld
|
| + AdbRemotePageCommand, |
| + content::BrowserThread::DeleteOnUIThread> { |
| + public: |
| + AdbRemotePageCommand(scoped_refptr<DevToolsAdbBridge::AndroidDevice> device, |
| + const std::string& socket, |
| + const std::string& command, |
| + const CommandCallback& callback) |
| + : device_(device), |
| + socket_(socket), |
| + command_(command), |
| + callback_(callback) { |
| + } |
| + |
| + void Run() { |
| + device_->HttpQuery(socket_, command_, callback_); |
| + } |
| + |
| + private: |
| + friend struct content::BrowserThread::DeleteOnThread< |
| + content::BrowserThread::UI>; |
| + friend class base::DeleteHelper<AdbRemotePageCommand>; |
| + |
| + virtual ~AdbRemotePageCommand() {} |
| + |
| + scoped_refptr<DevToolsAdbBridge::AndroidDevice> device_; |
| + const std::string socket_; |
| + const std::string command_; |
| + CommandCallback callback_; |
| +}; |
| + |
| +class DebuggerCommand : public AdbWebSocket::Delegate { |
|
pfeldman
2013/08/06 13:33:34
Lets split this into declaration and definition wi
Vladislav Kaznacheev
2013/08/07 09:35:12
Done.
|
| + public: |
| + DebuggerCommand( |
| + scoped_refptr<DevToolsAdbBridge::AndroidDevice> device, |
| + const std::string& socket_name, |
| + const std::string& debug_url, |
| + base::MessageLoop* adb_message_loop, |
| + const std::string& command) |
| + : command_(command) { |
| + web_socket_ = new AdbWebSocket( |
| + device, socket_name, debug_url, adb_message_loop, this); |
| + } |
| + |
| + private: |
| + virtual ~DebuggerCommand() {} |
| + |
| + virtual void OnSocketOpened() OVERRIDE { |
| + web_socket_->SendFrame(command_); |
| + web_socket_->Disconnect(); |
| + } |
| + |
| + virtual void OnFrameRead(const std::string& message) OVERRIDE {} |
| + |
| + virtual void OnSocketClosed(bool closed_by_device) OVERRIDE { |
| + delete this; |
|
pfeldman
2013/08/06 13:33:34
This object leaks when message loop closes.
Vladislav Kaznacheev
2013/08/07 09:35:12
Retaining DevToolsAdbBridge instance now to make s
|
| + } |
| + |
| + virtual bool ProcessIncomingMessage(const std::string& message) OVERRIDE { |
| + return false; |
| + } |
| + |
| + const std::string command_; |
| + scoped_refptr<AdbWebSocket> web_socket_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(DebuggerCommand); |
| +}; |
| + |
| } // namespace |
| const char kDevToolsChannelNameFormat[] = "%s_devtools_remote"; |
| @@ -508,6 +579,10 @@ class AgentHostDelegate : public content::DevToolsExternalAgentProxyDelegate, |
| profile_, frontend_url_, proxy_->GetAgentHost().get()); |
| } |
| + void SendCommand(const std::string& command) { |
| + SendMessageToBackend(command); |
| + } |
| + |
| private: |
| virtual ~AgentHostDelegate() { |
| g_host_delegates.Get().erase(id_); |
| @@ -585,7 +660,7 @@ DevToolsAdbBridge::RemotePage::RemotePage( |
| frontend_url_ = "https:" + frontend_url_.substr(5); |
| global_id_ = base::StringPrintf( |
| - "%s:%s:%s", device->serial().c_str(), socket_.c_str(), id_.c_str()); |
| + "page:%s:%s:%s", device->serial().c_str(), socket_.c_str(), id_.c_str()); |
| } |
| void DevToolsAdbBridge::RemotePage::Inspect(Profile* profile) { |
| @@ -600,6 +675,45 @@ void DevToolsAdbBridge::RemotePage::Inspect(Profile* profile) { |
| frontend_url_, bridge_->GetAdbMessageLoop(), profile); |
| } |
| +static void Noop(int, const std::string&) {} |
| + |
| +void DevToolsAdbBridge::RemotePage::Close() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + std::string request = base::StringPrintf(kClosePageRequest, id_.c_str()); |
| + scoped_refptr<AdbRemotePageCommand> close = |
| + new AdbRemotePageCommand(device_, socket_, request, base::Bind(&Noop)); |
| + bridge_->GetAdbMessageLoop()->PostTask(FROM_HERE, |
| + base::Bind(&AdbRemotePageCommand::Run, close)); |
| +} |
| + |
| +void DevToolsAdbBridge::RemotePage::Reload() { |
| + SendDebuggerCommand("Page.reload", NULL); |
| +} |
| + |
| +static const char kIdAttribute[] = "id"; |
| +static const char kMethodAttribute[] = "method"; |
| +static const char kParamsAttribute[] = "params"; |
| + |
| +void DevToolsAdbBridge::RemotePage::SendDebuggerCommand( |
| + const std::string& method, |
| + const base::DictionaryValue* params) { |
| + base::DictionaryValue command; |
| + command.SetInteger(kIdAttribute, -1); |
| + command.SetString(kMethodAttribute, method); |
| + if (params) |
| + command.Set(kParamsAttribute, params->DeepCopy()); |
| + std::string json_command; |
| + base::JSONWriter::Write(&command, &json_command); |
| + |
| + AgentHostDelegates::iterator it = |
| + g_host_delegates.Get().find(global_id()); |
| + if (it != g_host_delegates.Get().end()) |
|
pfeldman
2013/08/06 13:33:34
Please don't
Vladislav Kaznacheev
2013/08/07 09:35:12
Doing no longer.
|
| + it->second->SendCommand(json_command); |
| + else if (!debug_url_.empty()) |
| + new DebuggerCommand(device_, socket_, debug_url_, |
| + bridge_->GetAdbMessageLoop(), json_command); |
| +} |
| + |
| DevToolsAdbBridge::RemotePage::~RemotePage() { |
| } |
| @@ -612,6 +726,40 @@ DevToolsAdbBridge::RemoteBrowser::RemoteBrowser( |
| device_(device), |
| socket_(socket), |
| name_(name) { |
| + global_id_ = base::StringPrintf( |
| + "browser:%s:%s", device_->serial().c_str(), socket_.c_str()); |
| +} |
| + |
| +void DevToolsAdbBridge::RemoteBrowser::Open(const std::string& url) { |
| + scoped_refptr<AdbRemotePageCommand> command = |
| + new AdbRemotePageCommand( |
|
pfeldman
2013/08/06 13:33:34
JsonCommand
ProtocolCommand
Vladislav Kaznacheev
2013/08/07 09:35:12
Done.
|
| + device_, socket_, kNewPageRequest, |
| + base::Bind(&RemoteBrowser::PageCreatedOnHandlerThread, this, url)); |
| + bridge_->GetAdbMessageLoop()->PostTask(FROM_HERE, |
| + base::Bind(&AdbRemotePageCommand::Run, command)); |
| +} |
| + |
| +void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnHandlerThread( |
| + const std::string& url, int result, const std::string& response) { |
| + if (result < 0) |
| + return; |
| + std::string body = response.substr(result); |
|
pfeldman
2013/08/06 13:33:34
This is insane! Lets factor it out first plz. I kn
Vladislav Kaznacheev
2013/08/07 09:35:12
see https://chromiumcodereview.appspot.com/2242900
|
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + base::Bind(&RemoteBrowser::PageCreatedOnUIThread, this, body, url)); |
| +} |
| + |
| +void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnUIThread( |
| + const std::string& response, const std::string& url) { |
| + scoped_ptr<base::Value> value(base::JSONReader::Read(response)); |
| + base::DictionaryValue* dict; |
| + if (value && value->GetAsDictionary(&dict)) { |
| + scoped_refptr<RemotePage> new_page = |
| + new RemotePage(bridge_, device_, socket_, *dict); |
| + base::DictionaryValue params; |
| + params.SetString("url", url); |
| + new_page->SendDebuggerCommand("Page.navigate", ¶ms); |
| + } |
| } |
| DevToolsAdbBridge::RemoteBrowser::~RemoteBrowser() { |
| @@ -622,6 +770,7 @@ DevToolsAdbBridge::RemoteDevice::RemoteDevice( |
| scoped_refptr<AndroidDevice> device) |
| : bridge_(bridge), |
| device_(device) { |
| + global_id_ = base::StringPrintf("device:%s", device_->serial().c_str()); |
| } |
| DevToolsAdbBridge::RemoteDevice::~RemoteDevice() { |