Index: chrome/browser/devtools/device/cloud/devtools_bridge_client.cc |
diff --git a/chrome/browser/devtools/device/cloud/devtools_bridge_client.cc b/chrome/browser/devtools/device/cloud/devtools_bridge_client.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bbe6878fdacd5d63e85edb85e264d017dc323ce9 |
--- /dev/null |
+++ b/chrome/browser/devtools/device/cloud/devtools_bridge_client.cc |
@@ -0,0 +1,167 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/devtools/device/cloud/devtools_bridge_client.h" |
+ |
+#include "base/json/json_writer.h" |
+#include "chrome/browser/ui/browser.h" |
+#include "chrome/common/url_constants.h" |
+#include "content/public/browser/web_contents.h" |
+#include "content/public/browser/web_ui_data_source.h" |
+#include "content/public/browser/web_ui_message_handler.h" |
+#include "grit/devtools_bridge_client.h" |
+#include "grit/devtools_bridge_client_resources_map.h" |
+ |
+namespace { |
+ |
+class MessageDispatcher : public content::WebUIMessageHandler { |
+ public: |
+ class Delegate { |
+ public: |
pfeldman
2014/11/26 11:56:42
This looks like too many layers of indirection. Yo
|
+ virtual void OnLoaded() = 0; |
+ virtual void SendCommand(int request_id, |
+ const std::string& command) = 0; |
+ }; |
+ |
+ explicit MessageDispatcher(Delegate* delegate); |
+ |
+ void RegisterMessages() override; |
+ |
+ void StartSession(const std::string& device_id); |
+ |
+ private: |
+ void HandleLoaded(const base::ListValue* args); |
+ void HandleSendCommand(const base::ListValue* args); |
+ |
+ Delegate* const delegate_; |
+}; |
+ |
+class DevToolsBridgeClientImpl : public DevToolsBridgeClient, |
pfeldman
2014/11/26 11:56:42
Also needs a new name, typically this is Something
SeRya
2014/11/26 13:09:13
SomethigUI is typically content::WebUIController.
|
+ private MessageDispatcher::Delegate { |
+ public: |
+ DevToolsBridgeClientImpl(content::BrowserContext* context, |
+ DevToolsBridgeClient::Delegate* delegate); |
+ |
+ void StartSession(const std::string& device_id) override; |
+ |
+ private: |
+ // MessageDispatcher::Delegate |
+ void OnLoaded() override; |
+ void SendCommand(int request_id, |
+ const std::string& command) override; |
+ |
+ DevToolsBridgeClient::Delegate* const delegate_; |
+ const scoped_ptr<content::WebContents> web_contents_; |
+ MessageDispatcher dispatcher_; |
+ std::set<std::string> client_sessions_; |
+ bool is_loaded_; |
+}; |
+ |
+// MessageDispatcher |
+ |
+MessageDispatcher::MessageDispatcher(Delegate* delegate) |
+ : delegate_(delegate) { |
+} |
+ |
+void MessageDispatcher::RegisterMessages() { |
+ web_ui()->RegisterMessageCallback( |
+ "loaded", |
+ base::Bind(&MessageDispatcher::HandleLoaded, base::Unretained(this))); |
+ web_ui()->RegisterMessageCallback( |
+ "sendCommand", |
+ base::Bind(&MessageDispatcher::HandleSendCommand, base::Unretained(this))); |
+} |
+ |
+void MessageDispatcher::StartSession(const std::string& device_id) { |
+ web_ui()->CallJavascriptFunction( |
+ "WebClient.instance.startSession", |
dgozman
2014/11/26 11:33:25
Why WebClient? The naming should be consistent.
SeRya
2014/11/26 13:09:13
Will rename.
|
+ base::StringValue(device_id)); |
+} |
+ |
+void MessageDispatcher::HandleLoaded(const base::ListValue* args) { |
+ printf("!!!!!!!!!!!!!!!!!!!!!!MessageDispatcher::HandleLoaded\n"); |
+ delegate_->OnLoaded(); |
+} |
+ |
+void MessageDispatcher::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); |
+} |
+ |
+// DevToolsBridgeClientImpl |
+ |
+DevToolsBridgeClientImpl::DevToolsBridgeClientImpl( |
+ content::BrowserContext* context, |
+ DevToolsBridgeClient::Delegate* delegate) |
+ : delegate_(delegate), |
+ web_contents_(content::WebContents::Create( |
+ content::WebContents::CreateParams(context))), |
+ dispatcher_(this), |
+ is_loaded_(false) { |
+ web_contents_->GetController().LoadURL( |
+ GURL(chrome::kChromeUIDevToolsBridgeClientURL), |
+ content::Referrer(), |
+ ui::PAGE_TRANSITION_AUTO_TOPLEVEL, |
+ std::string()); |
+ web_contents_->GetWebUI()->AddMessageHandler(&dispatcher_); |
dgozman
2014/11/26 11:33:25
I'd move this call to DevToolsBridgeUI class.
SeRya
2014/11/26 13:09:13
Why? Here dispatcher_ is a member field easily acc
|
+} |
+ |
+void DevToolsBridgeClientImpl::StartSession(const std::string& device_id) { |
+ client_sessions_.insert(device_id); |
+ if (is_loaded_) |
+ dispatcher_.StartSession(device_id); |
+} |
+ |
+void DevToolsBridgeClientImpl::OnLoaded() { |
+ DCHECK(!is_loaded_); |
+ is_loaded_ = true; |
+ for (auto i = client_sessions_.begin(); i != client_sessions_.end(); ++i) { |
+ dispatcher_.StartSession(*i); |
+ } |
+} |
+ |
+void DevToolsBridgeClientImpl::SendCommand(int request_id, |
+ const std::string& command) { |
+ delegate_->SendCommand(command); |
+} |
+ |
+} // namespace |
+ |
+// DevToolsBridgeClient |
+ |
+// static |
+scoped_ptr<DevToolsBridgeClient> DevToolsBridgeClient::CreateInstance( |
+ content::BrowserContext* context, Delegate* delegate) { |
+ return make_scoped_ptr(new DevToolsBridgeClientImpl(context, delegate)); |
+} |
+ |
+// static |
+void DevToolsBridgeClient::AddResources( |
dgozman
2014/11/26 11:33:25
I think this belongs to DevToolsBridgeUI.
pfeldman
2014/11/26 11:56:42
I think this whole thing is DevToolsBridgeUI, or b
|
+ content::WebUIDataSource* data_source) { |
+ for (size_t i = 0; i < kDevtoolsBridgeClientSize; i++) { |
+ data_source->AddResourcePath(kDevtoolsBridgeClient[i].name, |
+ kDevtoolsBridgeClient[i].value); |
+ } |
+ data_source->SetDefaultResource(IDR_WEB_CLIENT_HTML); |
+} |