Chromium Code Reviews| Index: components/devtools_bridge/client/web_client.cc |
| diff --git a/components/devtools_bridge/client/web_client.cc b/components/devtools_bridge/client/web_client.cc |
| index d323db52e332d2e24d5640ec21331847ab42b112..e5e7d73db55ac09a91debcbbca25f66a8e9d2fb3 100644 |
| --- a/components/devtools_bridge/client/web_client.cc |
| +++ b/components/devtools_bridge/client/web_client.cc |
| @@ -3,28 +3,215 @@ |
| // found in the LICENSE file. |
| #include "components/devtools_bridge/client/web_client.h" |
| + |
| +#include <map> |
| + |
| +#include "base/bind.h" |
| +#include "base/json/json_writer.h" |
| +#include "base/memory/weak_ptr.h" |
| +#include "base/stl_util.h" |
| +#include "base/values.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/browser/web_contents_delegate.h" |
| +#include "content/public/browser/web_ui_message_handler.h" |
| namespace devtools_bridge { |
| namespace { |
| -class WebClientImpl : public WebClient, private content::WebContentsDelegate { |
| +class JSProxy : public content::WebUIMessageHandler { |
| public: |
| - WebClientImpl(content::BrowserContext* context, Delegate* delegate); |
| + class Delegate { |
| + public: |
| + virtual void OnLoaded() = 0; |
| + virtual void SendCommand(int request_id, |
| + const std::string& command) = 0; |
| + }; |
| + |
| + explicit JSProxy(Delegate* delegate); |
| + |
| + void RegisterMessages() override; |
| + |
| + void StartSession(const std::string& device_id); |
| + void StopSession(const std::string& device_id); |
| private: |
| + void HandleLoaded(const base::ListValue* args); |
| + void HandleSendCommand(const base::ListValue* args); |
| + |
| Delegate* const delegate_; |
| +}; |
| + |
| +class ClientSession { |
| +}; |
| + |
| +class WebClientImpl : public WebClient, |
| + private content::WebContentsDelegate, |
| + private JSProxy::Delegate, |
| + public base::SupportsWeakPtr<WebClientImpl> { |
| + public: |
| + WebClientImpl(content::BrowserContext* context, |
| + WebClient::Delegate* delegate); |
| + ~WebClientImpl(); |
| + |
| + // WebClient implementation. |
| + void Connect(const std::string& device_id) override; |
| + void Disconnect(const std::string& device_id) override; |
| + void DisconnectAll() override; |
| + |
| + private: |
| + typedef std::map<std::string, ClientSession*> ClientSessionMap; |
| + |
| + // JSProxy::Delegate |
| + void OnLoaded() override; |
| + void SendCommand(int request_id, |
| + const std::string& command) override; |
| + |
| + |
|
mnaganov (inactive)
2014/11/24 11:47:20
nit: extra empty line
|
| + void OnCommandSent(int request_id, |
| + const std::string& response); |
| + void OnCommandFailed(int request_id); |
| + |
| + ClientSessionMap client_session_map_; |
| + WebClient::Delegate* const delegate_; |
| + JSProxy js_proxy_; |
| const scoped_ptr<content::WebContents> web_contents_; |
| + bool is_loaded_; |
| }; |
| +// JSProxy implementation |
| + |
| +JSProxy::JSProxy(Delegate* delegate) |
| + : delegate_(delegate) { |
| +} |
| + |
| +void JSProxy::RegisterMessages() { |
| + web_ui()->RegisterMessageCallback( |
| + "loaded", |
| + base::Bind(&JSProxy::HandleLoaded, base::Unretained(this))); |
| + web_ui()->RegisterMessageCallback( |
| + "sendCommand", |
| + base::Bind(&JSProxy::HandleSendCommand, base::Unretained(this))); |
| +} |
| + |
| +void JSProxy::StartSession(const std::string& device_id) { |
| + web_ui()->CallJavascriptFunction( |
| + "WebClient.instance.startSession", |
| + base::StringValue(device_id)); |
| +} |
| + |
| +void JSProxy::StopSession(const std::string& device_id) { |
| + web_ui()->CallJavascriptFunction( |
| + "WebClient.instance.stopSession", |
| + base::StringValue(device_id)); |
| +} |
| + |
| +void JSProxy::HandleLoaded(const base::ListValue* args) { |
| + delegate_->OnLoaded(); |
| +} |
| + |
| +void JSProxy::HandleSendCommand(const base::ListValue* args) { |
| + if (args->GetSize() != 2) { |
| + DLOG(ERROR) << "Wrong number of arguments"; |
| + return; |
| + } |
| + int request_id; |
| + if (!args->GetInteger(0, &request_id)) { |
| + DLOG(ERROR) << "No request id"; |
| + return; |
| + } |
| + const base::DictionaryValue* command; |
| + if (!args->GetDictionary(1, &command)) { |
| + DLOG(ERROR) << "No message"; |
| + return; |
| + } |
| + |
| + std::string json; |
| + if (!base::JSONWriter::Write(command, &json)) { |
| + DLOG(ERROR) << "Failed to serialize message"; |
| + return; |
| + } |
| + |
| + delegate_->SendCommand(request_id, json); |
| +} |
| + |
| +// WebClientImpl implementation. |
| + |
| WebClientImpl::WebClientImpl(content::BrowserContext* context, |
| - Delegate* delegate) |
| + WebClient::Delegate* delegate) |
| : delegate_(delegate), |
| + js_proxy_(this), |
| web_contents_(content::WebContents::Create( |
| - content::WebContents::CreateParams(context))) { |
| + content::WebContents::CreateParams(context))), |
| + is_loaded_(false) { |
| web_contents_->SetDelegate(this); |
| + GURL url("chrome-devtools://bridge/web_client.html"); |
| + web_contents_->GetController().LoadURL(url, |
| + content::Referrer(), |
| + ui::PAGE_TRANSITION_AUTO_TOPLEVEL, |
| + std::string()); |
| + web_contents_->GetWebUI()->AddMessageHandler(&js_proxy_); |
| +} |
| + |
| +WebClientImpl::~WebClientImpl() { |
| + STLDeleteValues(&client_session_map_); |
| +} |
| + |
| +void WebClientImpl::Connect(const std::string& device_id) { |
| + if (client_session_map_.find(device_id) != client_session_map_.end()) |
| + return; |
| + |
| + if (is_loaded_) |
| + js_proxy_.StartSession(device_id); |
| + |
| + client_session_map_.insert(std::make_pair(device_id, new ClientSession())); |
| +} |
| + |
| +void WebClientImpl::Disconnect(const std::string& device_id) { |
| + ClientSessionMap::iterator session = client_session_map_.find(device_id); |
| + if (session == client_session_map_.end()) |
| + return; |
| + if (is_loaded_) |
| + js_proxy_.StartSession(device_id); |
| + |
| + delete session->second; |
| + client_session_map_.erase(session); |
| +} |
| + |
| +void WebClientImpl::DisconnectAll() { |
| + if (is_loaded_) { |
| + for (ClientSessionMap::iterator i = client_session_map_.begin(); |
| + i != client_session_map_.end(); ++i) { |
| + js_proxy_.StopSession(i->first); |
| + } |
| + } |
| + STLDeleteValues(&client_session_map_); |
| + client_session_map_.clear(); |
| +} |
| + |
| +void WebClientImpl::OnLoaded() { |
| + DCHECK(!is_loaded_); |
| + for (ClientSessionMap::iterator i = client_session_map_.begin(); |
| + i != client_session_map_.end(); ++i) { |
| + js_proxy_.StartSession(i->first); |
| + } |
| +} |
| + |
| +void WebClientImpl::SendCommand(int request_id, |
| + const std::string& command) { |
| + delegate_->SendCommand( |
| + command, |
| + base::Bind(&WebClientImpl::OnCommandSent, AsWeakPtr(), request_id), |
| + base::Bind(&WebClientImpl::OnCommandFailed, AsWeakPtr(), request_id)); |
| +} |
| + |
| +void WebClientImpl::OnCommandSent(int request_id, |
| + const std::string& response) { |
| + // TODO(serya): implement |
| +} |
| + |
| +void WebClientImpl::OnCommandFailed(int request_id) { |
| + // TODO(serya): implement |
| } |
| } // namespace |