From 265076f19ad78b09764e94727c61a75ed9dc4500 Mon Sep 17 00:00:00 2001 From: Adam Roben Date: Mon, 2 Dec 2013 12:38:24 -0500 Subject: [PATCH] Update for changes to devtools in Chrome 31 browser/devtools_embedder_message_dispatcher.* came from chrome/browser/devtools, and were modified just enough to compile within brightray. --- brightray/brightray.gyp | 2 + .../devtools_embedder_message_dispatcher.cc | 208 ++++++++++++++++++ .../devtools_embedder_message_dispatcher.h | 68 ++++++ .../browser/inspectable_web_contents_impl.cc | 11 +- .../browser/inspectable_web_contents_impl.h | 14 +- 5 files changed, 297 insertions(+), 6 deletions(-) create mode 100644 brightray/browser/devtools_embedder_message_dispatcher.cc create mode 100644 brightray/browser/devtools_embedder_message_dispatcher.h diff --git a/brightray/brightray.gyp b/brightray/brightray.gyp index 0a41a149048b..1781172b9703 100644 --- a/brightray/brightray.gyp +++ b/brightray/brightray.gyp @@ -35,6 +35,8 @@ 'browser/default_web_contents_delegate.cc', 'browser/default_web_contents_delegate.h', 'browser/default_web_contents_delegate_mac.mm', + 'browser/devtools_embedder_message_dispatcher.cc', + 'browser/devtools_embedder_message_dispatcher.h', 'browser/devtools_ui.cc', 'browser/devtools_ui.h', 'browser/download_manager_delegate.cc', diff --git a/brightray/browser/devtools_embedder_message_dispatcher.cc b/brightray/browser/devtools_embedder_message_dispatcher.cc new file mode 100644 index 000000000000..2d6c61ec1c83 --- /dev/null +++ b/brightray/browser/devtools_embedder_message_dispatcher.cc @@ -0,0 +1,208 @@ +// Copyright 2013 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-CHROMIUM file. + +#include "browser/devtools_embedder_message_dispatcher.h" + +#include "base/bind.h" +#include "base/json/json_reader.h" +#include "base/values.h" + +namespace brightray { + +namespace { + +static const char kFrontendHostMethod[] = "method"; +static const char kFrontendHostParams[] = "params"; + +bool GetValue(const base::ListValue& list, int pos, std::string& value) { + return list.GetString(pos, &value); +} + +bool GetValue(const base::ListValue& list, int pos, int& value) { + return list.GetInteger(pos, &value); +} + +bool GetValue(const base::ListValue& list, int pos, bool& value) { + return list.GetBoolean(pos, &value); +} + +template +struct StorageTraits { + typedef T StorageType; +}; + +template +struct StorageTraits { + typedef T StorageType; +}; + +template +class Argument { + public: + typedef typename StorageTraits::StorageType ValueType; + + Argument(const base::ListValue& list, int pos) { + valid_ = GetValue(list, pos, value_); + } + + ValueType value() const { return value_; } + bool valid() const { return valid_; } + + private: + ValueType value_; + bool valid_; +}; + +bool ParseAndHandle0(const base::Callback& handler, + const base::ListValue& list) { + handler.Run(); + return true; +} + +template +bool ParseAndHandle1(const base::Callback& handler, + const base::ListValue& list) { + if (list.GetSize() != 1) + return false; + Argument arg1(list, 0); + if (!arg1.valid()) + return false; + handler.Run(arg1.value()); + return true; +} + +template +bool ParseAndHandle2(const base::Callback& handler, + const base::ListValue& list) { + if (list.GetSize() != 2) + return false; + Argument arg1(list, 0); + if (!arg1.valid()) + return false; + Argument arg2(list, 1); + if (!arg2.valid()) + return false; + handler.Run(arg1.value(), arg2.value()); + return true; +} + +template +bool ParseAndHandle3(const base::Callback& handler, + const base::ListValue& list) { + if (list.GetSize() != 3) + return false; + Argument arg1(list, 0); + if (!arg1.valid()) + return false; + Argument arg2(list, 1); + if (!arg2.valid()) + return false; + Argument arg3(list, 2); + if (!arg3.valid()) + return false; + handler.Run(arg1.value(), arg2.value(), arg3.value()); + return true; +} + +typedef base::Callback ListValueParser; + +ListValueParser BindToListParser(const base::Callback& handler) { + return base::Bind(&ParseAndHandle0, handler); +} + +template +ListValueParser BindToListParser(const base::Callback& handler) { + return base::Bind(&ParseAndHandle1, handler); +} + +template +ListValueParser BindToListParser(const base::Callback& handler) { + return base::Bind(&ParseAndHandle2, handler); +} + +template +ListValueParser BindToListParser( + const base::Callback& handler) { + return base::Bind(&ParseAndHandle3, handler); +} + +} // namespace + +DevToolsEmbedderMessageDispatcher::DevToolsEmbedderMessageDispatcher( + Delegate* delegate) { + RegisterHandler("bringToFront", + BindToListParser(base::Bind(&Delegate::ActivateWindow, + base::Unretained(delegate)))); + RegisterHandler("closeWindow", + BindToListParser(base::Bind(&Delegate::CloseWindow, + base::Unretained(delegate)))); + RegisterHandler("moveWindowBy", + BindToListParser(base::Bind(&Delegate::MoveWindow, + base::Unretained(delegate)))); + RegisterHandler("requestSetDockSide", + BindToListParser(base::Bind(&Delegate::SetDockSide, + base::Unretained(delegate)))); + RegisterHandler("openInNewTab", + BindToListParser(base::Bind(&Delegate::OpenInNewTab, + base::Unretained(delegate)))); + RegisterHandler("save", + BindToListParser(base::Bind(&Delegate::SaveToFile, + base::Unretained(delegate)))); + RegisterHandler("append", + BindToListParser(base::Bind(&Delegate::AppendToFile, + base::Unretained(delegate)))); + RegisterHandler("requestFileSystems", + BindToListParser(base::Bind(&Delegate::RequestFileSystems, + base::Unretained(delegate)))); + RegisterHandler("addFileSystem", + BindToListParser(base::Bind(&Delegate::AddFileSystem, + base::Unretained(delegate)))); + RegisterHandler("removeFileSystem", + BindToListParser(base::Bind(&Delegate::RemoveFileSystem, + base::Unretained(delegate)))); + RegisterHandler("indexPath", + BindToListParser(base::Bind(&Delegate::IndexPath, + base::Unretained(delegate)))); + RegisterHandler("stopIndexing", + BindToListParser(base::Bind(&Delegate::StopIndexing, + base::Unretained(delegate)))); + RegisterHandler("searchInPath", + BindToListParser(base::Bind(&Delegate::SearchInPath, + base::Unretained(delegate)))); +} + +DevToolsEmbedderMessageDispatcher::~DevToolsEmbedderMessageDispatcher() {} + +void DevToolsEmbedderMessageDispatcher::Dispatch(const std::string& message) { + std::string method; + base::ListValue empty_params; + base::ListValue* params = &empty_params; + + base::DictionaryValue* dict; + scoped_ptr parsed_message(base::JSONReader::Read(message)); + if (!parsed_message || + !parsed_message->GetAsDictionary(&dict) || + !dict->GetString(kFrontendHostMethod, &method) || + (dict->HasKey(kFrontendHostParams) && + !dict->GetList(kFrontendHostParams, ¶ms))) { + LOG(ERROR) << "Cannot parse frontend host message: " << message; + return; + } + + HandlerMap::iterator it = handlers_.find(method); + if (it == handlers_.end()) { + LOG(ERROR) << "Unsupported frontend host method: " << message; + return; + } + + if (!it->second.Run(*params)) + LOG(ERROR) << "Invalid frontend host message parameters: " << message; +} + +void DevToolsEmbedderMessageDispatcher::RegisterHandler( + const std::string& method, const Handler& handler) { + handlers_[method] = handler; +} + +} // namespace brightray diff --git a/brightray/browser/devtools_embedder_message_dispatcher.h b/brightray/browser/devtools_embedder_message_dispatcher.h new file mode 100644 index 000000000000..df21050320e5 --- /dev/null +++ b/brightray/browser/devtools_embedder_message_dispatcher.h @@ -0,0 +1,68 @@ +// Copyright 2013 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-CHROMIUM file. + +#ifndef BRIGHTRAY_BROWSER_DEVTOOLS_EMBEDDER_MESSAGE_DISPATCHER_H_ +#define BRIGHTRAY_BROWSER_DEVTOOLS_EMBEDDER_MESSAGE_DISPATCHER_H_ + +#include +#include + +#include "base/callback.h" + +namespace base { +class ListValue; +} + +namespace brightray { + +/** + * Dispatcher for messages sent from the DevTools frontend running in an + * isolated renderer (on chrome-devtools://) to the embedder in the browser. + * + * The messages are sent via InspectorFrontendHost.sendMessageToEmbedder method. + */ +class DevToolsEmbedderMessageDispatcher { + public: + class Delegate { + public: + virtual ~Delegate() {} + + virtual void ActivateWindow() = 0; + virtual void CloseWindow() = 0; + virtual void MoveWindow(int x, int y) = 0; + virtual void SetDockSide(const std::string& side) = 0; + virtual void OpenInNewTab(const std::string& url) = 0; + virtual void SaveToFile(const std::string& url, + const std::string& content, + bool save_as) = 0; + virtual void AppendToFile(const std::string& url, + const std::string& content) = 0; + virtual void RequestFileSystems() = 0; + virtual void AddFileSystem() = 0; + virtual void RemoveFileSystem(const std::string& file_system_path) = 0; + virtual void IndexPath(int request_id, + const std::string& file_system_path) = 0; + virtual void StopIndexing(int request_id) = 0; + virtual void SearchInPath(int request_id, + const std::string& file_system_path, + const std::string& query) = 0; + }; + + explicit DevToolsEmbedderMessageDispatcher(Delegate* delegate); + + ~DevToolsEmbedderMessageDispatcher(); + + void Dispatch(const std::string& message); + + private: + typedef base::Callback Handler; + void RegisterHandler(const std::string& method, const Handler& handler); + + typedef std::map HandlerMap; + HandlerMap handlers_; +}; + +} // namespace brightray + +#endif // BRIGHTRAY_BROWSER_DEVTOOLS_EMBEDDER_MESSAGE_DISPATCHER_H_ diff --git a/brightray/browser/inspectable_web_contents_impl.cc b/brightray/browser/inspectable_web_contents_impl.cc index 5f5619532187..e3cefbe180c6 100644 --- a/brightray/browser/inspectable_web_contents_impl.cc +++ b/brightray/browser/inspectable_web_contents_impl.cc @@ -61,6 +61,9 @@ content::WebContents* InspectableWebContentsImpl::GetWebContents() const { void InspectableWebContentsImpl::ShowDevTools() { if (!devtools_web_contents_) { + embedder_message_dispatcher_.reset( + new DevToolsEmbedderMessageDispatcher(this)); + auto create_params = content::WebContents::CreateParams( web_contents_->GetBrowserContext()); devtools_web_contents_.reset(content::WebContents::Create(create_params)); @@ -103,9 +106,6 @@ void InspectableWebContentsImpl::UpdateFrontendDockSide() { void InspectableWebContentsImpl::ActivateWindow() { } -void InspectableWebContentsImpl::ChangeAttachedWindowHeight(unsigned height) { -} - void InspectableWebContentsImpl::CloseWindow() { view_->CloseDevTools(); devtools_web_contents_.reset(); @@ -162,6 +162,11 @@ void InspectableWebContentsImpl::SearchInPath( const std::string& query) { } +void InspectableWebContentsImpl::DispatchOnEmbedder( + const std::string& message) { + embedder_message_dispatcher_->Dispatch(message); +} + void InspectableWebContentsImpl::InspectedContentsClosing() { } diff --git a/brightray/browser/inspectable_web_contents_impl.h b/brightray/browser/inspectable_web_contents_impl.h index 50592fd3fc5c..804d8dccfe27 100644 --- a/brightray/browser/inspectable_web_contents_impl.h +++ b/brightray/browser/inspectable_web_contents_impl.h @@ -8,6 +8,8 @@ #include "browser/inspectable_web_contents.h" +#include "browser/devtools_embedder_message_dispatcher.h" + #include "content/public/browser/devtools_frontend_host_delegate.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" @@ -27,7 +29,8 @@ class InspectableWebContentsImpl : public InspectableWebContents, content::DevToolsFrontendHostDelegate, content::WebContentsObserver, - content::WebContentsDelegate { + content::WebContentsDelegate, + DevToolsEmbedderMessageDispatcher::Delegate { public: static void RegisterPrefs(PrefRegistrySimple* pref_registry); @@ -46,10 +49,9 @@ class InspectableWebContentsImpl : private: void UpdateFrontendDockSide(); - // content::DevToolsFrontendHostDelegate + // DevToolsEmbedderMessageDispacher::Delegate virtual void ActivateWindow() OVERRIDE; - virtual void ChangeAttachedWindowHeight(unsigned height) OVERRIDE; virtual void CloseWindow() OVERRIDE; virtual void MoveWindow(int x, int y) OVERRIDE; virtual void SetDockSide(const std::string& side) OVERRIDE; @@ -68,6 +70,10 @@ class InspectableWebContentsImpl : virtual void SearchInPath(int request_id, const std::string& file_system_path, const std::string& query) OVERRIDE; + + // content::DevToolsFrontendHostDelegate + + virtual void DispatchOnEmbedder(const std::string& message) OVERRIDE; virtual void InspectedContentsClosing() OVERRIDE; // content::WebContentsObserver @@ -92,6 +98,8 @@ class InspectableWebContentsImpl : scoped_refptr agent_host_; std::string dock_side_; + scoped_ptr embedder_message_dispatcher_; + DISALLOW_COPY_AND_ASSIGN(InspectableWebContentsImpl); };