Skip to content

Commit

Permalink
Migrate DevToolsWindow from specific to opaque frontend host messages
Browse files Browse the repository at this point in the history
TBR=jam (new file in chrome.gyp) 
BUG=278002

Review URL: https://chromiumcodereview.appspot.com/22972007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221418 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
kaznacheev@chromium.org committed Sep 5, 2013
1 parent 0012d2c commit 58f2878
Show file tree
Hide file tree
Showing 13 changed files with 312 additions and 325 deletions.
11 changes: 11 additions & 0 deletions chrome/browser/devtools/OWNERS
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@
pfeldman@chromium.org
yurys@chromium.org

# Changes to embedder messages require a security review.
# The list of reviewers is copied from content/common/OWNERS
per-file devtools_embedder_message_dispatcher.*=set noparent
per-file devtools_embedder_message_dispatcher.*=cdn@chromium.org
per-file devtools_embedder_message_dispatcher.*=cevans@chromium.org
per-file devtools_embedder_message_dispatcher.*=jln@chromium.org
per-file devtools_embedder_message_dispatcher.*=jschuh@chromium.org
per-file devtools_embedder_message_dispatcher.*=palmer@chromium.org
per-file devtools_embedder_message_dispatcher.*=tsepez@chromium.org
per-file devtools_embedder_message_dispatcher.*=kenrb@chromium.org
204 changes: 204 additions & 0 deletions chrome/browser/devtools/devtools_embedder_message_dispatcher.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
// 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 file.

#include "chrome/browser/devtools/devtools_embedder_message_dispatcher.h"

#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/values.h"

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 <typename T>
struct StorageTraits {
typedef T StorageType;
};

template <typename T>
struct StorageTraits<const T&> {
typedef T StorageType;
};

template <class A>
class Argument {
public:
typedef typename StorageTraits<A>::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<void(void)>& handler,
const base::ListValue& list) {
handler.Run();
return true;
}

template <class A1>
bool ParseAndHandle1(const base::Callback<void(A1)>& handler,
const base::ListValue& list) {
if (list.GetSize() != 1)
return false;
Argument<A1> arg1(list, 0);
if (!arg1.valid())
return false;
handler.Run(arg1.value());
return true;
}

template <class A1, class A2>
bool ParseAndHandle2(const base::Callback<void(A1, A2)>& handler,
const base::ListValue& list) {
if (list.GetSize() != 2)
return false;
Argument<A1> arg1(list, 0);
if (!arg1.valid())
return false;
Argument<A2> arg2(list, 1);
if (!arg2.valid())
return false;
handler.Run(arg1.value(), arg2.value());
return true;
}

template <class A1, class A2, class A3>
bool ParseAndHandle3(const base::Callback<void(A1, A2, A3)>& handler,
const base::ListValue& list) {
if (list.GetSize() != 3)
return false;
Argument<A1> arg1(list, 0);
if (!arg1.valid())
return false;
Argument<A2> arg2(list, 1);
if (!arg2.valid())
return false;
Argument<A3> arg3(list, 2);
if (!arg3.valid())
return false;
handler.Run(arg1.value(), arg2.value(), arg3.value());
return true;
}

typedef base::Callback<bool(const base::ListValue&)> ListValueParser;

ListValueParser BindToListParser(const base::Callback<void()>& handler) {
return base::Bind(&ParseAndHandle0, handler);
}

template <class A1>
ListValueParser BindToListParser(const base::Callback<void(A1)>& handler) {
return base::Bind(&ParseAndHandle1<A1>, handler);
}

template <class A1, class A2>
ListValueParser BindToListParser(const base::Callback<void(A1,A2)>& handler) {
return base::Bind(&ParseAndHandle2<A1, A2>, handler);
}

template <class A1, class A2, class A3>
ListValueParser BindToListParser(
const base::Callback<void(A1,A2,A3)>& handler) {
return base::Bind(&ParseAndHandle3<A1, A2, A3>, 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<base::Value> parsed_message(base::JSONReader::Read(message));
if (!parsed_message ||
!parsed_message->GetAsDictionary(&dict) ||
!dict->GetString(kFrontendHostMethod, &method) ||
(dict->HasKey(kFrontendHostParams) &&
!dict->GetList(kFrontendHostParams, &params))) {
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;
}
64 changes: 64 additions & 0 deletions chrome/browser/devtools/devtools_embedder_message_dispatcher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// 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 file.

#ifndef CHROME_BROWSER_DEVTOOLS_DEVTOOLS_EMBEDDER_MESSAGE_DISPATCHER_H_
#define CHROME_BROWSER_DEVTOOLS_DEVTOOLS_EMBEDDER_MESSAGE_DISPATCHER_H_

#include <map>
#include <string>

#include "base/callback.h"

namespace base {
class ListValue;
}

/**
* 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<bool(const base::ListValue&)> Handler;
void RegisterHandler(const std::string& method, const Handler& handler);

typedef std::map<std::string, Handler> HandlerMap;
HandlerMap handlers_;
};

#endif // CHROME_BROWSER_DEVTOOLS_DEVTOOLS_EMBEDDER_MESSAGE_DISPATCHER_H_
11 changes: 7 additions & 4 deletions chrome/browser/devtools/devtools_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,9 @@ DevToolsWindow::DevToolsWindow(Profile* profile,
if (inspected_rvh)
inspected_contents_observer_.reset(new InspectedWebContentsObserver(
content::WebContents::FromRenderViewHost(inspected_rvh)));

embedder_message_dispatcher_.reset(
new DevToolsEmbedderMessageDispatcher(this));
}

// static
Expand Down Expand Up @@ -832,17 +835,17 @@ void DevToolsWindow::WebContentsFocused(content::WebContents* contents) {
inspected_browser->window()->WebContentsFocused(contents);
}

void DevToolsWindow::DispatchOnEmbedder(const std::string& message) {
embedder_message_dispatcher_->Dispatch(message);
}

void DevToolsWindow::ActivateWindow() {
if (IsDocked() && GetInspectedBrowserWindow())
web_contents_->GetView()->Focus();
else if (!IsDocked() && !browser_->window()->IsActive())
browser_->window()->Activate();
}

void DevToolsWindow::ChangeAttachedWindowHeight(unsigned height) {
NOTREACHED(); // TODO(dgozman): This is not used anymore, remove.
}

void DevToolsWindow::CloseWindow() {
DCHECK(IsDocked());
content::DevToolsManager::GetInstance()->ClientHostClosing(
Expand Down
11 changes: 8 additions & 3 deletions chrome/browser/devtools/devtools_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "chrome/browser/devtools/devtools_embedder_message_dispatcher.h"
#include "chrome/browser/devtools/devtools_file_helper.h"
#include "chrome/browser/devtools/devtools_file_system_indexer.h"
#include "chrome/browser/devtools/devtools_toggle_action.h"
Expand Down Expand Up @@ -55,7 +56,8 @@ enum DevToolsDockSide {

class DevToolsWindow : private content::NotificationObserver,
private content::WebContentsDelegate,
private content::DevToolsFrontendHostDelegate {
private content::DevToolsFrontendHostDelegate,
private DevToolsEmbedderMessageDispatcher::Delegate {
public:
typedef base::Callback<void(bool)> InfoBarCallback;

Expand Down Expand Up @@ -181,9 +183,11 @@ class DevToolsWindow : private content::NotificationObserver,
const content::FileChooserParams& params) OVERRIDE;
virtual void WebContentsFocused(content::WebContents* contents) OVERRIDE;

// content::DevToolsFrontendHostDelegate:
// content::DevToolsFrontendHostDelegate override:
virtual void DispatchOnEmbedder(const std::string& message) OVERRIDE;

// DevToolsEmbedderMessageDispatcher::Delegate overrides:
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;
Expand Down Expand Up @@ -266,6 +270,7 @@ class DevToolsWindow : private content::NotificationObserver,
int height_;
DevToolsDockSide dock_side_before_minimized_;

scoped_ptr<DevToolsEmbedderMessageDispatcher> embedder_message_dispatcher_;
DISALLOW_COPY_AND_ASSIGN(DevToolsWindow);
};

Expand Down
2 changes: 2 additions & 0 deletions chrome/chrome.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@
'browser/devtools/browser_list_tabcontents_provider.h',
'browser/devtools/devtools_adb_bridge.cc',
'browser/devtools/devtools_adb_bridge.h',
'browser/devtools/devtools_embedder_message_dispatcher.cc',
'browser/devtools/devtools_embedder_message_dispatcher.h',
'browser/devtools/devtools_file_helper.cc',
'browser/devtools/devtools_file_helper.h',
'browser/devtools/devtools_file_system_indexer.cc',
Expand Down
Loading

0 comments on commit 58f2878

Please sign in to comment.