From 31eefc6af87114088aa7611d99f92a53e959f455 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 5 Jun 2015 11:03:47 +0800 Subject: [PATCH 1/6] Update to new devtools messages --- .../devtools_embedder_message_dispatcher.cc | 319 ++++++++---------- .../devtools_embedder_message_dispatcher.h | 43 ++- browser/inspectable_web_contents_impl.cc | 156 ++++++--- browser/inspectable_web_contents_impl.h | 32 +- 4 files changed, 295 insertions(+), 255 deletions(-) diff --git a/browser/devtools_embedder_message_dispatcher.cc b/browser/devtools_embedder_message_dispatcher.cc index bb64846320b43..c5b90fccef9c5 100644 --- a/browser/devtools_embedder_message_dispatcher.cc +++ b/browser/devtools_embedder_message_dispatcher.cc @@ -11,21 +11,23 @@ namespace brightray { namespace { -bool GetValue(const base::ListValue& list, int pos, std::string& value) { - return list.GetString(pos, &value); +using DispatchCallback = DevToolsEmbedderMessageDispatcher::DispatchCallback; + +bool GetValue(const base::Value* value, std::string* result) { + return value->GetAsString(result); } -bool GetValue(const base::ListValue& list, int pos, int& value) { - return list.GetInteger(pos, &value); +bool GetValue(const base::Value* value, int* result) { + return value->GetAsInteger(result); } -bool GetValue(const base::ListValue& list, int pos, bool& value) { - return list.GetBoolean(pos, &value); +bool GetValue(const base::Value* value, bool* result) { + return value->GetAsBoolean(result); } -bool GetValue(const base::ListValue& list, int pos, gfx::Rect& rect) { +bool GetValue(const base::Value* value, gfx::Rect* rect) { const base::DictionaryValue* dict; - if (!list.GetDictionary(pos, &dict)) + if (!value->GetAsDictionary(&dict)) return false; int x = 0; int y = 0; @@ -36,217 +38,164 @@ bool GetValue(const base::ListValue& list, int pos, gfx::Rect& rect) { !dict->GetInteger("width", &width) || !dict->GetInteger("height", &height)) return false; - rect.SetRect(x, y, width, height); + rect->SetRect(x, y, width, height); return true; } template struct StorageTraits { - typedef T StorageType; + using StorageType = T; }; template struct StorageTraits { - typedef T StorageType; + using StorageType = T; }; -template -class Argument { - public: - typedef typename StorageTraits::StorageType ValueType; - - Argument(const base::ListValue& list, int pos) { - valid_ = GetValue(list, pos, value_); +template +struct ParamTuple { + bool Parse(const base::ListValue& list, + const base::ListValue::const_iterator& it) { + return it == list.end(); } - ValueType value() const { return value_; } - bool valid() const { return valid_; } - - private: - ValueType value_; - bool valid_; + template + void Apply(const H& handler, As... args) { + handler.Run(args...); + } }; -bool ParseAndHandle0(const base::Callback& handler, - const base::ListValue& list) { - handler.Run(); - return true; -} +template +struct ParamTuple { + bool Parse(const base::ListValue& list, + const base::ListValue::const_iterator& it) { + return it != list.end() && GetValue(*it, &head) && tail.Parse(list, it + 1); + } -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 + void Apply(const H& handler, As... args) { + tail.template Apply(handler, args..., head); + } -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; -} + typename StorageTraits::StorageType head; + ParamTuple tail; +}; -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()) +template +bool ParseAndHandle(const base::Callback& handler, + const DispatchCallback& callback, + const base::ListValue& list) { + ParamTuple tuple; + if (!tuple.Parse(list, list.begin())) return false; - handler.Run(arg1.value(), arg2.value(), arg3.value()); + tuple.Apply(handler); return true; } -template -bool ParseAndHandle3(const base::Callback& handler, - const base::ListValue& list) { - if (list.GetSize() != 3) +template +bool ParseAndHandleWithCallback( + const base::Callback& handler, + const DispatchCallback& callback, + const base::ListValue& list) { + ParamTuple tuple; + if (!tuple.Parse(list, list.begin())) 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; - Argument arg4(list, 3); - if (!arg4.valid()) - return false; - handler.Run(arg1.value(), arg2.value(), arg3.value(), arg4.value()); + tuple.Apply(handler, callback); return true; } +} // namespace -typedef base::Callback ListValueParser; - -ListValueParser BindToListParser(const base::Callback& handler) { - return base::Bind(&ParseAndHandle0, handler); -} +/** + * Dispatcher for messages sent from the frontend running in an + * isolated renderer (chrome-devtools:// or chrome://inspect) to the embedder + * in the browser. + * + * The messages are sent via InspectorFrontendHost.sendMessageToEmbedder or + * chrome.send method accordingly. + */ +class DispatcherImpl : public DevToolsEmbedderMessageDispatcher { + public: + ~DispatcherImpl() override {} -template -ListValueParser BindToListParser(const base::Callback& handler) { - return base::Bind(&ParseAndHandle1, handler); -} + bool Dispatch(const DispatchCallback& callback, + const std::string& method, + const base::ListValue* params) override { + HandlerMap::iterator it = handlers_.find(method); + return it != handlers_.end() && it->second.Run(callback, *params); + } -template -ListValueParser BindToListParser(const base::Callback& handler) { - return base::Bind(&ParseAndHandle2, handler); -} + template + void RegisterHandler(const std::string& method, + void (Delegate::*handler)(As...), + Delegate* delegate) { + handlers_[method] = base::Bind(&ParseAndHandle, + base::Bind(handler, + base::Unretained(delegate))); + } -template -ListValueParser BindToListParser( - const base::Callback& handler) { - return base::Bind(&ParseAndHandle3, handler); -} + template + void RegisterHandlerWithCallback( + const std::string& method, + void (Delegate::*handler)(const DispatchCallback&, As...), + Delegate* delegate) { + handlers_[method] = base::Bind(&ParseAndHandleWithCallback, + base::Bind(handler, + base::Unretained(delegate))); + } -template -ListValueParser BindToListParser( - const base::Callback& handler) { - return base::Bind(&ParseAndHandle3, handler); -} -} // namespace + private: + using Handler = base::Callback; + using HandlerMap = std::map; + HandlerMap handlers_; +}; -DevToolsEmbedderMessageDispatcher::DevToolsEmbedderMessageDispatcher( +// static +DevToolsEmbedderMessageDispatcher* +DevToolsEmbedderMessageDispatcher::CreateForDevToolsFrontend( Delegate* delegate) { - RegisterHandler("bringToFront", - BindToListParser(base::Bind(&Delegate::ActivateWindow, - base::Unretained(delegate)))); - RegisterHandler("closeWindow", - BindToListParser(base::Bind(&Delegate::CloseWindow, - base::Unretained(delegate)))); - RegisterHandler("setInspectedPageBounds", - BindToListParser(base::Bind(&Delegate::SetInspectedPageBounds, - base::Unretained(delegate)))); - RegisterHandler("inspectElementCompleted", - BindToListParser(base::Bind(&Delegate::InspectElementCompleted, - base::Unretained(delegate)))); - RegisterHandler("moveWindowBy", - BindToListParser(base::Bind(&Delegate::MoveWindow, - base::Unretained(delegate)))); - RegisterHandler("setIsDocked", - BindToListParser(base::Bind(&Delegate::SetIsDocked, - 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("upgradeDraggedFileSystemPermissions", - BindToListParser(base::Bind(&Delegate::UpgradeDraggedFileSystemPermissions, - 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)))); - RegisterHandler("zoomIn", - BindToListParser(base::Bind(&Delegate::ZoomIn, - base::Unretained(delegate)))); - RegisterHandler("zoomOut", - BindToListParser(base::Bind(&Delegate::ZoomOut, - base::Unretained(delegate)))); - RegisterHandler("resetZoom", - BindToListParser(base::Bind(&Delegate::ResetZoom, - base::Unretained(delegate)))); -} - -DevToolsEmbedderMessageDispatcher::~DevToolsEmbedderMessageDispatcher() {} - -std::string DevToolsEmbedderMessageDispatcher::Dispatch( - const std::string& method, base::ListValue* params) { - HandlerMap::iterator it = handlers_.find(method); - if (it == handlers_.end()) - return "Unsupported frontend host method: " + method; - - if (!it->second.Run(*params)) - return "Invalid frontend host message parameters: " + method; - return ""; -} - -void DevToolsEmbedderMessageDispatcher::RegisterHandler( - const std::string& method, const Handler& handler) { - handlers_[method] = handler; + DispatcherImpl* d = new DispatcherImpl(); + + d->RegisterHandler("bringToFront", &Delegate::ActivateWindow, delegate); + d->RegisterHandler("closeWindow", &Delegate::CloseWindow, delegate); + d->RegisterHandler("loadCompleted", &Delegate::LoadCompleted, delegate); + d->RegisterHandler("setInspectedPageBounds", + &Delegate::SetInspectedPageBounds, delegate); + d->RegisterHandler("inspectElementCompleted", + &Delegate::InspectElementCompleted, delegate); + d->RegisterHandler("inspectedURLChanged", + &Delegate::InspectedURLChanged, delegate); + d->RegisterHandlerWithCallback("setIsDocked", + &Delegate::SetIsDocked, delegate); + d->RegisterHandler("openInNewTab", &Delegate::OpenInNewTab, delegate); + d->RegisterHandler("save", &Delegate::SaveToFile, delegate); + d->RegisterHandler("append", &Delegate::AppendToFile, delegate); + d->RegisterHandler("requestFileSystems", + &Delegate::RequestFileSystems, delegate); + d->RegisterHandler("addFileSystem", &Delegate::AddFileSystem, delegate); + d->RegisterHandler("removeFileSystem", &Delegate::RemoveFileSystem, delegate); + d->RegisterHandler("upgradeDraggedFileSystemPermissions", + &Delegate::UpgradeDraggedFileSystemPermissions, delegate); + d->RegisterHandler("indexPath", &Delegate::IndexPath, delegate); + d->RegisterHandlerWithCallback("loadNetworkResource", + &Delegate::LoadNetworkResource, delegate); + d->RegisterHandler("stopIndexing", &Delegate::StopIndexing, delegate); + d->RegisterHandler("searchInPath", &Delegate::SearchInPath, delegate); + d->RegisterHandler("setWhitelistedShortcuts", + &Delegate::SetWhitelistedShortcuts, delegate); + d->RegisterHandler("zoomIn", &Delegate::ZoomIn, delegate); + d->RegisterHandler("zoomOut", &Delegate::ZoomOut, delegate); + d->RegisterHandler("resetZoom", &Delegate::ResetZoom, delegate); + d->RegisterHandler("setDevicesUpdatesEnabled", + &Delegate::SetDevicesUpdatesEnabled, delegate); + d->RegisterHandler("sendMessageToBrowser", + &Delegate::SendMessageToBrowser, delegate); + d->RegisterHandler("recordActionUMA", &Delegate::RecordActionUMA, delegate); + d->RegisterHandlerWithCallback("sendJsonRequest", + &Delegate::SendJsonRequest, delegate); + return d; } } // namespace brightray diff --git a/browser/devtools_embedder_message_dispatcher.h b/browser/devtools_embedder_message_dispatcher.h index defe16c1f43aa..851a2f490586b 100644 --- a/browser/devtools_embedder_message_dispatcher.h +++ b/browser/devtools_embedder_message_dispatcher.h @@ -15,6 +15,7 @@ namespace base { class ListValue; +class Value; } namespace brightray { @@ -29,14 +30,18 @@ class DevToolsEmbedderMessageDispatcher { public: class Delegate { public: + using DispatchCallback = base::Callback; + virtual ~Delegate() {} virtual void ActivateWindow() = 0; virtual void CloseWindow() = 0; + virtual void LoadCompleted() = 0; virtual void SetInspectedPageBounds(const gfx::Rect& rect) = 0; virtual void InspectElementCompleted() = 0; - virtual void MoveWindow(int x, int y) = 0; - virtual void SetIsDocked(bool docked) = 0; + virtual void InspectedURLChanged(const std::string& url) = 0; + virtual void SetIsDocked(const DispatchCallback& callback, + bool is_docked) = 0; virtual void OpenInNewTab(const std::string& url) = 0; virtual void SaveToFile(const std::string& url, const std::string& content, @@ -48,29 +53,37 @@ class DevToolsEmbedderMessageDispatcher { virtual void RemoveFileSystem(const std::string& file_system_path) = 0; virtual void UpgradeDraggedFileSystemPermissions( const std::string& file_system_url) = 0; - virtual void IndexPath(int request_id, + virtual void IndexPath(int index_request_id, const std::string& file_system_path) = 0; - virtual void StopIndexing(int request_id) = 0; - virtual void SearchInPath(int request_id, + virtual void StopIndexing(int index_request_id) = 0; + virtual void LoadNetworkResource(const DispatchCallback& callback, + const std::string& url, + const std::string& headers, + int stream_id) = 0; + virtual void SearchInPath(int search_request_id, const std::string& file_system_path, const std::string& query) = 0; + virtual void SetWhitelistedShortcuts(const std::string& message) = 0; virtual void ZoomIn() = 0; virtual void ZoomOut() = 0; virtual void ResetZoom() = 0; + virtual void SetDevicesUpdatesEnabled(bool enabled) = 0; + virtual void SendMessageToBrowser(const std::string& message) = 0; + virtual void RecordActionUMA(const std::string& name, int action) = 0; + virtual void SendJsonRequest(const DispatchCallback& callback, + const std::string& browser_id, + const std::string& url) = 0; }; - explicit DevToolsEmbedderMessageDispatcher(Delegate* delegate); - - ~DevToolsEmbedderMessageDispatcher(); - - std::string Dispatch(const std::string& method, base::ListValue* params); + using DispatchCallback = Delegate::DispatchCallback; - private: - typedef base::Callback Handler; - void RegisterHandler(const std::string& method, const Handler& handler); + virtual ~DevToolsEmbedderMessageDispatcher() {} + virtual bool Dispatch(const DispatchCallback& callback, + const std::string& method, + const base::ListValue* params) = 0; - typedef std::map HandlerMap; - HandlerMap handlers_; + static DevToolsEmbedderMessageDispatcher* CreateForDevToolsFrontend( + Delegate* delegate); }; } // namespace brightray diff --git a/browser/inspectable_web_contents_impl.cc b/browser/inspectable_web_contents_impl.cc index 27bf3dbac1755..43fc7132db724 100644 --- a/browser/inspectable_web_contents_impl.cc +++ b/browser/inspectable_web_contents_impl.cc @@ -12,6 +12,8 @@ #include "browser/inspectable_web_contents_view.h" #include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "base/metrics/histogram.h" #include "base/prefs/pref_registry_simple.h" #include "base/prefs/pref_service.h" #include "base/strings/stringprintf.h" @@ -41,6 +43,11 @@ const char kFrontendHostId[] = "id"; const char kFrontendHostMethod[] = "method"; const char kFrontendHostParams[] = "params"; +const char kDevToolsActionTakenHistogram[] = "DevTools.ActionTaken"; +const int kDevToolsActionTakenBoundary = 100; +const char kDevToolsPanelShownHistogram[] = "DevTools.PanelShown"; +const int kDevToolsPanelShownBoundary = 20; + void RectToDictionary(const gfx::Rect& bounds, base::DictionaryValue* dict) { dict->SetInteger("x", bounds.x()); dict->SetInteger("y", bounds.y()); @@ -57,34 +64,6 @@ void DictionaryToRect(const base::DictionaryValue& dict, gfx::Rect* bounds) { *bounds = gfx::Rect(x, y, width, height); } -bool ParseMessage(const std::string& message, - std::string* method, - base::ListValue* params, - int* id) { - scoped_ptr parsed_message(base::JSONReader::Read(message)); - if (!parsed_message) - return false; - - base::DictionaryValue* dict = NULL; - if (!parsed_message->GetAsDictionary(&dict)) - return false; - if (!dict->GetString(kFrontendHostMethod, method)) - return false; - - // "params" is optional. - if (dict->HasKey(kFrontendHostParams)) { - base::ListValue* internal_params; - if (dict->GetList(kFrontendHostParams, &internal_params)) - params->Swap(internal_params); - else - return false; - } - - *id = 0; - dict->GetInteger(kFrontendHostId, id); - return true; -} - double GetZoomLevelForWebContents(content::WebContents* web_contents) { return content::HostZoomMap::GetZoomLevel(web_contents); } @@ -123,7 +102,8 @@ InspectableWebContentsImpl::InspectableWebContentsImpl( content::WebContents* web_contents) : web_contents_(web_contents), can_dock_(true), - delegate_(nullptr) { + delegate_(nullptr), + weak_factory_(this) { auto context = static_cast(web_contents_->GetBrowserContext()); auto bounds_dict = context->prefs()->GetDictionary(kDevToolsBoundsPref); if (bounds_dict) @@ -152,7 +132,7 @@ void InspectableWebContentsImpl::ShowDevTools() { // SetIsDocked is called *BEFORE* ShowDevTools. if (!devtools_web_contents_) { embedder_message_dispatcher_.reset( - new DevToolsEmbedderMessageDispatcher(this)); + DevToolsEmbedderMessageDispatcher::CreateForDevToolsFrontend(this)); content::WebContents::CreateParams create_params(web_contents_->GetBrowserContext()); devtools_web_contents_.reset(content::WebContents::Create(create_params)); @@ -200,6 +180,29 @@ void InspectableWebContentsImpl::Detach() { agent_host_ = nullptr; } +void InspectableWebContentsImpl::CallClientFunction(const std::string& function_name, + const base::Value* arg1, + const base::Value* arg2, + const base::Value* arg3) { + std::string javascript = function_name + "("; + if (arg1) { + std::string json; + base::JSONWriter::Write(arg1, &json); + javascript.append(json); + if (arg2) { + base::JSONWriter::Write(arg2, &json); + javascript.append(", ").append(json); + if (arg3) { + base::JSONWriter::Write(arg3, &json); + javascript.append(", ").append(json); + } + } + } + javascript.append(");"); + devtools_web_contents_->GetMainFrame()->ExecuteJavaScript( + base::UTF8ToUTF16(javascript)); +} + gfx::Rect InspectableWebContentsImpl::GetDevToolsBounds() const { return devtools_bounds_; } @@ -219,6 +222,9 @@ void InspectableWebContentsImpl::CloseWindow() { devtools_web_contents()->DispatchBeforeUnload(false); } +void InspectableWebContentsImpl::LoadCompleted() { +} + void InspectableWebContentsImpl::SetInspectedPageBounds(const gfx::Rect& rect) { DevToolsContentsResizingStrategy strategy(rect); if (contents_resizing_strategy_.Equals(strategy)) @@ -231,11 +237,21 @@ void InspectableWebContentsImpl::SetInspectedPageBounds(const gfx::Rect& rect) { void InspectableWebContentsImpl::InspectElementCompleted() { } -void InspectableWebContentsImpl::MoveWindow(int x, int y) { +void InspectableWebContentsImpl::InspectedURLChanged(const std::string& url) { +} + +void InspectableWebContentsImpl::LoadNetworkResource( + const DispatchCallback& callback, + const std::string& url, + const std::string& headers, + int stream_id) { } -void InspectableWebContentsImpl::SetIsDocked(bool docked) { +void InspectableWebContentsImpl::SetIsDocked(const DispatchCallback& callback, + bool docked) { view_->SetIsDocked(docked); + if (!callback.is_null()) + callback.Run(nullptr); } void InspectableWebContentsImpl::OpenInNewTab(const std::string& url) { @@ -253,12 +269,6 @@ void InspectableWebContentsImpl::AppendToFile( delegate_->DevToolsAppendToFile(url, content); } -void InspectableWebContentsImpl::WebContentsFocused( - content::WebContents* contents) { - if (delegate_) - delegate_->DevToolsFocused(); -} - void InspectableWebContentsImpl::RequestFileSystems() { devtools_web_contents()->GetMainFrame()->ExecuteJavaScript( base::ASCIIToUTF16("DevToolsAPI.fileSystemsLoaded([])")); @@ -292,6 +302,9 @@ void InspectableWebContentsImpl::SearchInPath( const std::string& query) { } +void InspectableWebContentsImpl::SetWhitelistedShortcuts(const std::string& message) { +} + void InspectableWebContentsImpl::ZoomIn() { double level = GetZoomLevelForWebContents(devtools_web_contents()); SetZoomLevelForWebContents(devtools_web_contents(), GetNextZoomLevel(level, false)); @@ -306,26 +319,56 @@ void InspectableWebContentsImpl::ResetZoom() { SetZoomLevelForWebContents(devtools_web_contents(), 0.); } +void InspectableWebContentsImpl::SetDevicesUpdatesEnabled(bool enabled) { +} + +void InspectableWebContentsImpl::SendMessageToBrowser(const std::string& message) { + if (agent_host_.get()) + agent_host_->DispatchProtocolMessage(message); +} + +void InspectableWebContentsImpl::RecordActionUMA(const std::string& name, int action) { + if (name == kDevToolsActionTakenHistogram) + UMA_HISTOGRAM_ENUMERATION(name, action, kDevToolsActionTakenBoundary); + else if (name == kDevToolsPanelShownHistogram) + UMA_HISTOGRAM_ENUMERATION(name, action, kDevToolsPanelShownBoundary); +} + +void InspectableWebContentsImpl::SendJsonRequest(const DispatchCallback& callback, + const std::string& browser_id, + const std::string& url) { + callback.Run(nullptr); +} + void InspectableWebContentsImpl::HandleMessageFromDevToolsFrontend(const std::string& message) { std::string method; - base::ListValue params; - int id; - if (!ParseMessage(message, &method, ¶ms, &id)) { + base::ListValue empty_params; + base::ListValue* params = &empty_params; + + base::DictionaryValue* dict = NULL; + 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) << "Invalid message was sent to embedder: " << message; return; } - - std::string error = embedder_message_dispatcher_->Dispatch(method, ¶ms); - if (id) { - std::string ack = base::StringPrintf( - "DevToolsAPI.embedderMessageAck(%d, \"%s\");", id, error.c_str()); - devtools_web_contents()->GetMainFrame()->ExecuteJavaScript(base::UTF8ToUTF16(ack)); - } + int id = 0; + dict->GetInteger(kFrontendHostId, &id); + embedder_message_dispatcher_->Dispatch( + base::Bind(&InspectableWebContentsImpl::SendMessageAck, + weak_factory_.GetWeakPtr(), + id), + method, + params); } void InspectableWebContentsImpl::HandleMessageFromDevToolsFrontendToBackend( const std::string& message) { - agent_host_->DispatchProtocolMessage(message); + if (agent_host_.get()) + agent_host_->DispatchProtocolMessage(message); } void InspectableWebContentsImpl::DispatchProtocolMessage( @@ -356,7 +399,7 @@ void InspectableWebContentsImpl::DidFinishLoad(content::RenderFrameHost* render_ // If the devtools can dock, "SetIsDocked" will be called by devtools itself. if (!can_dock_) - SetIsDocked(false); + SetIsDocked(DispatchCallback(), false); } void InspectableWebContentsImpl::WebContentsDestroyed() { @@ -400,4 +443,17 @@ void InspectableWebContentsImpl::CloseContents(content::WebContents* source) { CloseDevTools(); } +void InspectableWebContentsImpl::WebContentsFocused( + content::WebContents* contents) { + if (delegate_) + delegate_->DevToolsFocused(); +} + +void InspectableWebContentsImpl::SendMessageAck(int request_id, + const base::Value* arg) { + base::FundamentalValue id_value(request_id); + CallClientFunction("DevToolsAPI.embedderMessageAck", + &id_value, arg, nullptr); +} + } // namespace brightray diff --git a/browser/inspectable_web_contents_impl.h b/browser/inspectable_web_contents_impl.h index 655f77ad0a08d..bde6e1b4aac82 100644 --- a/browser/inspectable_web_contents_impl.h +++ b/browser/inspectable_web_contents_impl.h @@ -11,6 +11,7 @@ #include "browser/devtools_contents_resizing_strategy.h" #include "browser/devtools_embedder_message_dispatcher.h" +#include "base/memory/weak_ptr.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_frontend_host.h" #include "content/public/browser/web_contents_delegate.h" @@ -51,6 +52,10 @@ class InspectableWebContentsImpl : void AttachTo(const scoped_refptr&) override; void Detach(); + void CallClientFunction(const std::string& function_name, + const base::Value* arg1, + const base::Value* arg2, + const base::Value* arg3); // Return the last position and size of devtools window. gfx::Rect GetDevToolsBounds() const; @@ -71,10 +76,15 @@ class InspectableWebContentsImpl : // DevToolsEmbedderMessageDispacher::Delegate void ActivateWindow() override; void CloseWindow() override; + void LoadCompleted() override; void SetInspectedPageBounds(const gfx::Rect& rect) override; void InspectElementCompleted() override; - void MoveWindow(int x, int y) override; - void SetIsDocked(bool docked) override; + void InspectedURLChanged(const std::string& url) override; + void LoadNetworkResource(const DispatchCallback& callback, + const std::string& url, + const std::string& headers, + int stream_id) override; + void SetIsDocked(const DispatchCallback& callback, bool is_docked) override; void OpenInNewTab(const std::string& url) override; void SaveToFile(const std::string& url, const std::string& content, @@ -86,15 +96,22 @@ class InspectableWebContentsImpl : void RemoveFileSystem(const std::string& file_system_path) override; void UpgradeDraggedFileSystemPermissions( const std::string& file_system_url) override; - void IndexPath(int request_id, + void IndexPath(int index_request_id, const std::string& file_system_path) override; - void StopIndexing(int request_id) override; - void SearchInPath(int request_id, + void StopIndexing(int index_request_id) override; + void SearchInPath(int search_request_id, const std::string& file_system_path, const std::string& query) override; + void SetWhitelistedShortcuts(const std::string& message) override; void ZoomIn() override; void ZoomOut() override; void ResetZoom() override; + void SetDevicesUpdatesEnabled(bool enabled) override; + void SendMessageToBrowser(const std::string& message) override; + void RecordActionUMA(const std::string& name, int action) override; + void SendJsonRequest(const DispatchCallback& callback, + const std::string& browser_id, + const std::string& url) override; // content::DevToolsFrontendHostDelegate: void HandleMessageFromDevToolsFrontend(const std::string& message) override; @@ -133,6 +150,9 @@ class InspectableWebContentsImpl : void CloseContents(content::WebContents* source) override; void WebContentsFocused(content::WebContents* contents) override; + void SendMessageAck(int request_id, + const base::Value* arg1); + scoped_ptr web_contents_; scoped_ptr devtools_web_contents_; scoped_ptr view_; @@ -147,6 +167,8 @@ class InspectableWebContentsImpl : InspectableWebContentsDelegate* delegate_; + base::WeakPtrFactory weak_factory_; + DISALLOW_COPY_AND_ASSIGN(InspectableWebContentsImpl); }; From 08eaf94d13f59dcd039dd849a692bd2048deda7d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 5 Jun 2015 11:20:20 +0800 Subject: [PATCH 2/6] Handle network requests from devtools --- browser/inspectable_web_contents_impl.cc | 100 +++++++++++++++++++++++ browser/inspectable_web_contents_impl.h | 11 ++- 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/browser/inspectable_web_contents_impl.cc b/browser/inspectable_web_contents_impl.cc index 43fc7132db724..bc3a9aba54f0a 100644 --- a/browser/inspectable_web_contents_impl.cc +++ b/browser/inspectable_web_contents_impl.cc @@ -19,10 +19,14 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/devtools_http_handler.h" #include "content/public/browser/host_zoom_map.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" +#include "net/http/http_response_headers.h" +#include "net/url_request/url_fetcher.h" +#include "net/url_request/url_fetcher_response_writer.h" namespace brightray { @@ -86,6 +90,59 @@ double GetNextZoomLevel(double level, bool out) { return level; } +// ResponseWriter ------------------------------------------------------------- + +class ResponseWriter : public net::URLFetcherResponseWriter { + public: + ResponseWriter(base::WeakPtr bindings, int stream_id); + ~ResponseWriter() override; + + // URLFetcherResponseWriter overrides: + int Initialize(const net::CompletionCallback& callback) override; + int Write(net::IOBuffer* buffer, + int num_bytes, + const net::CompletionCallback& callback) override; + int Finish(const net::CompletionCallback& callback) override; + + private: + base::WeakPtr bindings_; + int stream_id_; + + DISALLOW_COPY_AND_ASSIGN(ResponseWriter); +}; + +ResponseWriter::ResponseWriter(base::WeakPtr bindings, + int stream_id) + : bindings_(bindings), + stream_id_(stream_id) { +} + +ResponseWriter::~ResponseWriter() { +} + +int ResponseWriter::Initialize(const net::CompletionCallback& callback) { + return net::OK; +} + +int ResponseWriter::Write(net::IOBuffer* buffer, + int num_bytes, + const net::CompletionCallback& callback) { + base::FundamentalValue* id = new base::FundamentalValue(stream_id_); + base::StringValue* chunk = + new base::StringValue(std::string(buffer->data(), num_bytes)); + + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(&InspectableWebContentsImpl::CallClientFunction, + bindings_, "DevToolsAPI.streamWrite", + base::Owned(id), base::Owned(chunk), nullptr)); + return num_bytes; +} + +int ResponseWriter::Finish(const net::CompletionCallback& callback) { + return net::OK; +} + } // namespace // Implemented separately on each platform. @@ -245,6 +302,24 @@ void InspectableWebContentsImpl::LoadNetworkResource( const std::string& url, const std::string& headers, int stream_id) { + GURL gurl(url); + if (!gurl.is_valid()) { + base::DictionaryValue response; + response.SetInteger("statusCode", 404); + callback.Run(&response); + return; + } + + auto browser_context = static_cast(devtools_web_contents_->GetBrowserContext()); + + net::URLFetcher* fetcher = + net::URLFetcher::Create(gurl, net::URLFetcher::GET, this); + pending_requests_[fetcher] = callback; + fetcher->SetRequestContext(browser_context->url_request_context_getter()); + fetcher->SetExtraRequestHeaders(headers); + fetcher->SaveResponseWithWriter(scoped_ptr( + new ResponseWriter(weak_factory_.GetWeakPtr(), stream_id))); + fetcher->Start(); } void InspectableWebContentsImpl::SetIsDocked(const DispatchCallback& callback, @@ -406,6 +481,9 @@ void InspectableWebContentsImpl::WebContentsDestroyed() { agent_host_->DetachClient(); Observe(nullptr); agent_host_ = nullptr; + + for (const auto& pair : pending_requests_) + delete pair.first; } bool InspectableWebContentsImpl::AddMessageToConsole( @@ -449,6 +527,28 @@ void InspectableWebContentsImpl::WebContentsFocused( delegate_->DevToolsFocused(); } +void InspectableWebContentsImpl::OnURLFetchComplete(const net::URLFetcher* source) { + DCHECK(source); + PendingRequestsMap::iterator it = pending_requests_.find(source); + DCHECK(it != pending_requests_.end()); + + base::DictionaryValue response; + base::DictionaryValue* headers = new base::DictionaryValue(); + net::HttpResponseHeaders* rh = source->GetResponseHeaders(); + response.SetInteger("statusCode", rh ? rh->response_code() : 200); + response.Set("headers", headers); + + void* iterator = NULL; + std::string name; + std::string value; + while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value)) + headers->SetString(name, value); + + it->second.Run(&response); + pending_requests_.erase(it); + delete source; +} + void InspectableWebContentsImpl::SendMessageAck(int request_id, const base::Value* arg) { base::FundamentalValue id_value(request_id); diff --git a/browser/inspectable_web_contents_impl.h b/browser/inspectable_web_contents_impl.h index bde6e1b4aac82..932b0fd6a9468 100644 --- a/browser/inspectable_web_contents_impl.h +++ b/browser/inspectable_web_contents_impl.h @@ -16,6 +16,7 @@ #include "content/public/browser/devtools_frontend_host.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" +#include "net/url_request/url_fetcher_delegate.h" #include "ui/gfx/geometry/rect.h" class PrefRegistrySimple; @@ -35,7 +36,8 @@ class InspectableWebContentsImpl : public content::DevToolsAgentHostClient, public content::WebContentsObserver, public content::WebContentsDelegate, - public DevToolsEmbedderMessageDispatcher::Delegate { + public DevToolsEmbedderMessageDispatcher::Delegate, + public net::URLFetcherDelegate { public: static void RegisterPrefs(PrefRegistrySimple* pref_registry); @@ -130,7 +132,7 @@ class InspectableWebContentsImpl : const GURL& validated_url) override; void WebContentsDestroyed() override; - // content::WebContentsDelegate + // content::WebContentsDelegate: bool AddMessageToConsole(content::WebContents* source, int32 level, const base::string16& message, @@ -150,6 +152,9 @@ class InspectableWebContentsImpl : void CloseContents(content::WebContents* source) override; void WebContentsFocused(content::WebContents* contents) override; + // net::URLFetcherDelegate: + void OnURLFetchComplete(const net::URLFetcher* source) override; + void SendMessageAck(int request_id, const base::Value* arg1); @@ -167,6 +172,8 @@ class InspectableWebContentsImpl : InspectableWebContentsDelegate* delegate_; + using PendingRequestsMap = std::map; + PendingRequestsMap pending_requests_; base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(InspectableWebContentsImpl); From bb27b147d44b5eb8e32e9e5ab72e8e260d2c72ad Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 5 Jun 2015 11:58:27 +0800 Subject: [PATCH 3/6] Avoid calling JavaScript of devtools WebContents too early It would craete a context that window.location is about:blank --- browser/inspectable_web_contents_impl.cc | 31 ++++++++++++++++++------ browser/inspectable_web_contents_impl.h | 1 + 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/browser/inspectable_web_contents_impl.cc b/browser/inspectable_web_contents_impl.cc index bc3a9aba54f0a..3242316989f09 100644 --- a/browser/inspectable_web_contents_impl.cc +++ b/browser/inspectable_web_contents_impl.cc @@ -52,6 +52,8 @@ const int kDevToolsActionTakenBoundary = 100; const char kDevToolsPanelShownHistogram[] = "DevTools.PanelShown"; const int kDevToolsPanelShownBoundary = 20; +const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4; + void RectToDictionary(const gfx::Rect& bounds, base::DictionaryValue* dict) { dict->SetInteger("x", bounds.x()); dict->SetInteger("y", bounds.y()); @@ -159,6 +161,7 @@ InspectableWebContentsImpl::InspectableWebContentsImpl( content::WebContents* web_contents) : web_contents_(web_contents), can_dock_(true), + frontend_loaded_(false), delegate_(nullptr), weak_factory_(this) { auto context = static_cast(web_contents_->GetBrowserContext()); @@ -280,6 +283,7 @@ void InspectableWebContentsImpl::CloseWindow() { } void InspectableWebContentsImpl::LoadCompleted() { + frontend_loaded_ = true; } void InspectableWebContentsImpl::SetInspectedPageBounds(const gfx::Rect& rect) { @@ -345,8 +349,8 @@ void InspectableWebContentsImpl::AppendToFile( } void InspectableWebContentsImpl::RequestFileSystems() { - devtools_web_contents()->GetMainFrame()->ExecuteJavaScript( - base::ASCIIToUTF16("DevToolsAPI.fileSystemsLoaded([])")); + devtools_web_contents()->GetMainFrame()->ExecuteJavaScript( + base::ASCIIToUTF16("DevToolsAPI.fileSystemsLoaded([])")); } void InspectableWebContentsImpl::AddFileSystem() { @@ -448,9 +452,22 @@ void InspectableWebContentsImpl::HandleMessageFromDevToolsFrontendToBackend( void InspectableWebContentsImpl::DispatchProtocolMessage( content::DevToolsAgentHost* agent_host, const std::string& message) { - std::string code = "DevToolsAPI.dispatchMessage(" + message + ");"; - base::string16 javascript = base::UTF8ToUTF16(code); - web_contents()->GetMainFrame()->ExecuteJavaScript(javascript); + if (!frontend_loaded_) + return; + + if (message.length() < kMaxMessageChunkSize) { + base::string16 javascript = base::UTF8ToUTF16( + "DevToolsAPI.dispatchMessage(" + message + ");"); + devtools_web_contents_->GetMainFrame()->ExecuteJavaScript(javascript); + return; + } + + base::FundamentalValue total_size(static_cast(message.length())); + for (size_t pos = 0; pos < message.length(); pos += kMaxMessageChunkSize) { + base::StringValue message_value(message.substr(pos, kMaxMessageChunkSize)); + CallClientFunction("DevToolsAPI.dispatchMessageChunk", + &message_value, pos ? NULL : &total_size, NULL); + } } void InspectableWebContentsImpl::AgentHostClosed( @@ -478,9 +495,9 @@ void InspectableWebContentsImpl::DidFinishLoad(content::RenderFrameHost* render_ } void InspectableWebContentsImpl::WebContentsDestroyed() { - agent_host_->DetachClient(); Observe(nullptr); - agent_host_ = nullptr; + Detach(); + frontend_loaded_ = false; for (const auto& pair : pending_requests_) delete pair.first; diff --git a/browser/inspectable_web_contents_impl.h b/browser/inspectable_web_contents_impl.h index 932b0fd6a9468..aec9548b98a7f 100644 --- a/browser/inspectable_web_contents_impl.h +++ b/browser/inspectable_web_contents_impl.h @@ -167,6 +167,7 @@ class InspectableWebContentsImpl : DevToolsContentsResizingStrategy contents_resizing_strategy_; gfx::Rect devtools_bounds_; bool can_dock_; + bool frontend_loaded_; scoped_ptr embedder_message_dispatcher_; From 18c50e06e8afe6877418fd31f214c2e06309b01a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 5 Jun 2015 12:07:27 +0800 Subject: [PATCH 4/6] Update cpplint --- browser/browser_context.cc | 4 +- browser/browser_context.h | 4 +- browser/browser_main_parts.h | 12 ++--- .../devtools_embedder_message_dispatcher.cc | 2 +- browser/devtools_ui.cc | 21 +++++---- browser/inspectable_web_contents_view_mac.h | 12 ++--- browser/linux/notification_presenter_linux.cc | 7 +-- .../media/media_capture_devices_dispatcher.h | 10 ++--- browser/url_request_context_getter.h | 4 +- .../inspectable_web_contents_view_views.h | 16 +++---- browser/views/views_delegate.h | 44 +++++++++---------- browser/web_ui_controller_factory.h | 10 ++--- common/main_delegate.h | 6 +-- vendor/google-styleguide | 2 +- 14 files changed, 77 insertions(+), 77 deletions(-) diff --git a/browser/browser_context.cc b/browser/browser_context.cc index c4aa7d186d8cd..3e0e271164bfa 100644 --- a/browser/browser_context.cc +++ b/browser/browser_context.cc @@ -33,11 +33,11 @@ class BrowserContext::ResourceContext : public content::ResourceContext { } private: - virtual net::HostResolver* GetHostResolver() override { + net::HostResolver* GetHostResolver() override { return getter_->host_resolver(); } - virtual net::URLRequestContext* GetRequestContext() override { + net::URLRequestContext* GetRequestContext() override { return getter_->GetURLRequestContext(); } diff --git a/browser/browser_context.h b/browser/browser_context.h index d7f957477f153..5cddd0a494e67 100644 --- a/browser/browser_context.h +++ b/browser/browser_context.h @@ -40,9 +40,9 @@ class BrowserContext : public content::BrowserContext, virtual void RegisterPrefs(PrefRegistrySimple* pref_registry) {} // URLRequestContextGetter::Delegate: - virtual net::NetworkDelegate* CreateNetworkDelegate() override; + net::NetworkDelegate* CreateNetworkDelegate() override; - virtual base::FilePath GetPath() const override; + base::FilePath GetPath() const override; private: class ResourceContext; diff --git a/browser/browser_main_parts.h b/browser/browser_main_parts.h index a5ba51508b46c..e8d7c323c78ae 100644 --- a/browser/browser_main_parts.h +++ b/browser/browser_main_parts.h @@ -39,12 +39,12 @@ class BrowserMainParts : public content::BrowserMainParts { protected: // content::BrowserMainParts: - virtual void PreEarlyInitialization() override; - virtual void ToolkitInitialized() override; - virtual void PreMainMessageLoopStart() override; - virtual void PreMainMessageLoopRun() override; - virtual void PostMainMessageLoopRun() override; - virtual int PreCreateThreads() override; + void PreEarlyInitialization() override; + void ToolkitInitialized() override; + void PreMainMessageLoopStart() override; + void PreMainMessageLoopRun() override; + void PostMainMessageLoopRun() override; + int PreCreateThreads() override; // Subclasses should override this to provide their own BrowserContxt // implementation. The caller takes ownership of the returned object. diff --git a/browser/devtools_embedder_message_dispatcher.cc b/browser/devtools_embedder_message_dispatcher.cc index c5b90fccef9c5..cb44ec16d8602 100644 --- a/browser/devtools_embedder_message_dispatcher.cc +++ b/browser/devtools_embedder_message_dispatcher.cc @@ -104,7 +104,7 @@ bool ParseAndHandleWithCallback( return true; } -} // namespace +} // namespace /** * Dispatcher for messages sent from the frontend running in an diff --git a/browser/devtools_ui.cc b/browser/devtools_ui.cc index 30a974fccfc7b..9b5eba7d6fc29 100644 --- a/browser/devtools_ui.cc +++ b/browser/devtools_ui.cc @@ -52,18 +52,17 @@ std::string GetMimeTypeForPath(const std::string& path) { class BundledDataSource : public content::URLDataSource { public: - explicit BundledDataSource() { - } + BundledDataSource() {} // content::URLDataSource implementation. - virtual std::string GetSource() const override { + std::string GetSource() const override { return kChromeUIDevToolsBundledHost; } - virtual void StartDataRequest(const std::string& path, - int render_process_id, - int render_view_id, - const GotDataCallback& callback) override { + void StartDataRequest(const std::string& path, + int render_process_id, + int render_view_id, + const GotDataCallback& callback) override { std::string filename = PathWithoutParams(path); int resource_id = @@ -79,19 +78,19 @@ class BundledDataSource : public content::URLDataSource { callback.Run(bytes.get()); } - virtual std::string GetMimeType(const std::string& path) const override { + std::string GetMimeType(const std::string& path) const override { return GetMimeTypeForPath(path); } - virtual bool ShouldAddContentSecurityPolicy() const override { + bool ShouldAddContentSecurityPolicy() const override { return false; } - virtual bool ShouldDenyXFrameOptions() const override { + bool ShouldDenyXFrameOptions() const override { return false; } - virtual bool ShouldServeMimeTypeAsContentTypeHeader() const override { + bool ShouldServeMimeTypeAsContentTypeHeader() const override { return true; } diff --git a/browser/inspectable_web_contents_view_mac.h b/browser/inspectable_web_contents_view_mac.h index 6a81d642c8d93..fbe19adaebda0 100644 --- a/browser/inspectable_web_contents_view_mac.h +++ b/browser/inspectable_web_contents_view_mac.h @@ -17,12 +17,12 @@ class InspectableWebContentsViewMac : public InspectableWebContentsView { InspectableWebContentsImpl* inspectable_web_contents_impl); virtual ~InspectableWebContentsViewMac(); - virtual gfx::NativeView GetNativeView() const override; - virtual void ShowDevTools() override; - virtual void CloseDevTools() override; - virtual bool IsDevToolsViewShowing() override; - virtual void SetIsDocked(bool docked) override; - virtual void SetContentsResizingStrategy( + gfx::NativeView GetNativeView() const override; + void ShowDevTools() override; + void CloseDevTools() override; + bool IsDevToolsViewShowing() override; + void SetIsDocked(bool docked) override; + void SetContentsResizingStrategy( const DevToolsContentsResizingStrategy& strategy) override; InspectableWebContentsImpl* inspectable_web_contents() { diff --git a/browser/linux/notification_presenter_linux.cc b/browser/linux/notification_presenter_linux.cc index 9baa4474e980b..0c688906a7b69 100644 --- a/browser/linux/notification_presenter_linux.cc +++ b/browser/linux/notification_presenter_linux.cc @@ -30,7 +30,7 @@ static bool UnityIsRunning() { struct DBusConnection* bus = NULL; dbus_error_init(&err); - + bus = dbus_bus_get(DBUS_BUS_SESSION, &err); if (dbus_error_is_set(&err)) { g_debug("Failed to get Session Bus reference"); @@ -39,7 +39,7 @@ static bool UnityIsRunning() { goto out; } - + unity_result = dbus_bus_name_has_owner(bus, "com.canonical.indicator.session", &err); if (dbus_error_is_set(&err)) { @@ -107,7 +107,8 @@ void NotificationPresenterLinux::ShowNotification( // Zen Nature" is difficult, we will test for the presence of the indicate // dbus service if (!UnityIsRunning()) { - notify_notification_add_action(notification, "default", "View", OnNotificationViewThunk, this, nullptr); + notify_notification_add_action( + notification, "default", "View", OnNotificationViewThunk, this, nullptr); } GdkPixbuf* pixbuf = libgtk2ui::GdkPixbufFromSkBitmap(icon); diff --git a/browser/media/media_capture_devices_dispatcher.h b/browser/media/media_capture_devices_dispatcher.h index f89f9b02203bc..be369a2ff61f3 100644 --- a/browser/media/media_capture_devices_dispatcher.h +++ b/browser/media/media_capture_devices_dispatcher.h @@ -51,17 +51,17 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver { void DisableDeviceEnumerationForTesting(); // Overridden from content::MediaObserver: - virtual void OnAudioCaptureDevicesChanged() override; - virtual void OnVideoCaptureDevicesChanged() override; - virtual void OnMediaRequestStateChanged( + void OnAudioCaptureDevicesChanged() override; + void OnVideoCaptureDevicesChanged() override; + void OnMediaRequestStateChanged( int render_process_id, int render_view_id, int page_request_id, const GURL& security_origin, content::MediaStreamType stream_type, content::MediaRequestState state) override; - virtual void OnCreatingAudioStream(int render_process_id, - int render_view_id) override; + void OnCreatingAudioStream(int render_process_id, + int render_view_id) override; private: friend struct DefaultSingletonTraits; diff --git a/browser/url_request_context_getter.h b/browser/url_request_context_getter.h index 599bf6c4d228c..d1f847fc968eb 100644 --- a/browser/url_request_context_getter.h +++ b/browser/url_request_context_getter.h @@ -52,8 +52,8 @@ class URLRequestContextGetter : public net::URLRequestContextGetter { virtual ~URLRequestContextGetter(); // net::URLRequestContextGetter: - virtual net::URLRequestContext* GetURLRequestContext() override; - virtual scoped_refptr GetNetworkTaskRunner() const override; + net::URLRequestContext* GetURLRequestContext() override; + scoped_refptr GetNetworkTaskRunner() const override; net::HostResolver* host_resolver(); diff --git a/browser/views/inspectable_web_contents_view_views.h b/browser/views/inspectable_web_contents_view_views.h index 80934755692d9..4e25035046320 100644 --- a/browser/views/inspectable_web_contents_view_views.h +++ b/browser/views/inspectable_web_contents_view_views.h @@ -24,13 +24,13 @@ class InspectableWebContentsViewViews : public InspectableWebContentsView, ~InspectableWebContentsViewViews(); // InspectableWebContentsView: - virtual views::View* GetView() override; - virtual views::View* GetWebView() override; - virtual void ShowDevTools() override; - virtual void CloseDevTools() override; - virtual bool IsDevToolsViewShowing() override; - virtual void SetIsDocked(bool docked) override; - virtual void SetContentsResizingStrategy( + views::View* GetView() override; + views::View* GetWebView() override; + void ShowDevTools() override; + void CloseDevTools() override; + bool IsDevToolsViewShowing() override; + void SetIsDocked(bool docked) override; + void SetContentsResizingStrategy( const DevToolsContentsResizingStrategy& strategy) override; InspectableWebContentsImpl* inspectable_web_contents() { @@ -39,7 +39,7 @@ class InspectableWebContentsViewViews : public InspectableWebContentsView, private: // views::View: - virtual void Layout() override; + void Layout() override; // Owns us. InspectableWebContentsImpl* inspectable_web_contents_; diff --git a/browser/views/views_delegate.h b/browser/views/views_delegate.h index bd1e7bc2b6beb..157660aa5d092 100644 --- a/browser/views/views_delegate.h +++ b/browser/views/views_delegate.h @@ -17,42 +17,42 @@ class ViewsDelegate : public views::ViewsDelegate { protected: // views::ViewsDelegate: - virtual void SaveWindowPlacement(const views::Widget* window, - const std::string& window_name, - const gfx::Rect& bounds, - ui::WindowShowState show_state) override; - virtual bool GetSavedWindowPlacement( + void SaveWindowPlacement(const views::Widget* window, + const std::string& window_name, + const gfx::Rect& bounds, + ui::WindowShowState show_state) override; + bool GetSavedWindowPlacement( const views::Widget* widget, const std::string& window_name, gfx::Rect* bounds, ui::WindowShowState* show_state) const override; - virtual void NotifyAccessibilityEvent( + void NotifyAccessibilityEvent( views::View* view, ui::AXEvent event_type) override; - virtual void NotifyMenuItemFocused(const base::string16& menu_name, - const base::string16& menu_item_name, - int item_index, - int item_count, - bool has_submenu) override; + void NotifyMenuItemFocused(const base::string16& menu_name, + const base::string16& menu_item_name, + int item_index, + int item_count, + bool has_submenu) override; #if defined(OS_WIN) - virtual HICON GetDefaultWindowIcon() const override; - virtual HICON GetSmallWindowIcon() const override; - virtual bool IsWindowInMetro(gfx::NativeWindow window) const override; + HICON GetDefaultWindowIcon() const override; + HICON GetSmallWindowIcon() const override; + bool IsWindowInMetro(gfx::NativeWindow window) const override; #elif defined(OS_LINUX) && !defined(OS_CHROMEOS) - virtual gfx::ImageSkia* GetDefaultWindowIcon() const override; + gfx::ImageSkia* GetDefaultWindowIcon() const override; #endif - virtual views::NonClientFrameView* CreateDefaultNonClientFrameView( + views::NonClientFrameView* CreateDefaultNonClientFrameView( views::Widget* widget) override; - virtual void AddRef() override; - virtual void ReleaseRef() override; - virtual content::WebContents* CreateWebContents( + void AddRef() override; + void ReleaseRef() override; + content::WebContents* CreateWebContents( content::BrowserContext* browser_context, content::SiteInstance* site_instance) override; - virtual void OnBeforeWidgetInit( + void OnBeforeWidgetInit( views::Widget::InitParams* params, views::internal::NativeWidgetDelegate* delegate) override; - virtual base::TimeDelta GetDefaultTextfieldObscuredRevealDuration() override; - virtual bool WindowManagerProvidesTitleBar(bool maximized) override; + base::TimeDelta GetDefaultTextfieldObscuredRevealDuration() override; + bool WindowManagerProvidesTitleBar(bool maximized) override; private: DISALLOW_COPY_AND_ASSIGN(ViewsDelegate); diff --git a/browser/web_ui_controller_factory.h b/browser/web_ui_controller_factory.h index ed99e3247c57b..6f860841affe0 100644 --- a/browser/web_ui_controller_factory.h +++ b/browser/web_ui_controller_factory.h @@ -18,13 +18,13 @@ class WebUIControllerFactory : public content::WebUIControllerFactory { explicit WebUIControllerFactory(BrowserContext* browser_context); virtual ~WebUIControllerFactory(); - virtual content::WebUI::TypeID GetWebUIType( + content::WebUI::TypeID GetWebUIType( content::BrowserContext* browser_context, const GURL& url) const override; - virtual bool UseWebUIForURL(content::BrowserContext* browser_context, + bool UseWebUIForURL(content::BrowserContext* browser_context, + const GURL& url) const override; + bool UseWebUIBindingsForURL(content::BrowserContext* browser_context, const GURL& url) const override; - virtual bool UseWebUIBindingsForURL(content::BrowserContext* browser_context, - const GURL& url) const override; - virtual content::WebUIController* CreateWebUIControllerForURL( + content::WebUIController* CreateWebUIControllerForURL( content::WebUI* web_ui, const GURL& url) const override; diff --git a/common/main_delegate.h b/common/main_delegate.h index 153013b3c210b..58349944746df 100644 --- a/common/main_delegate.h +++ b/common/main_delegate.h @@ -49,11 +49,11 @@ class MainDelegate : public content::ContentMainDelegate { virtual void OverrideFrameworkBundlePath(); #endif - virtual bool BasicStartupComplete(int* exit_code) override; - virtual void PreSandboxStartup() override; + bool BasicStartupComplete(int* exit_code) override; + void PreSandboxStartup() override; private: - virtual content::ContentBrowserClient* CreateContentBrowserClient() override; + content::ContentBrowserClient* CreateContentBrowserClient() override; void InitializeResourceBundle(); diff --git a/vendor/google-styleguide b/vendor/google-styleguide index 8025f5495c04f..ba88c8a53f1b5 160000 --- a/vendor/google-styleguide +++ b/vendor/google-styleguide @@ -1 +1 @@ -Subproject commit 8025f5495c04f1cf9e0d65a0aaa97b58c304faf7 +Subproject commit ba88c8a53f1b563c43fc063cc048e5efdc238c18 From 019e663822ecddbf3907d0d3cd168434e11b7258 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 5 Jun 2015 12:10:01 +0800 Subject: [PATCH 5/6] No more need to override DidFinishLoad --- browser/inspectable_web_contents_impl.cc | 17 +++++------------ browser/inspectable_web_contents_impl.h | 2 -- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/browser/inspectable_web_contents_impl.cc b/browser/inspectable_web_contents_impl.cc index 3242316989f09..5d109e123e0bf 100644 --- a/browser/inspectable_web_contents_impl.cc +++ b/browser/inspectable_web_contents_impl.cc @@ -284,6 +284,11 @@ void InspectableWebContentsImpl::CloseWindow() { void InspectableWebContentsImpl::LoadCompleted() { frontend_loaded_ = true; + view_->ShowDevTools(); + + // If the devtools can dock, "SetIsDocked" will be called by devtools itself. + if (!can_dock_) + SetIsDocked(DispatchCallback(), false); } void InspectableWebContentsImpl::SetInspectedPageBounds(const gfx::Rect& rect) { @@ -482,18 +487,6 @@ void InspectableWebContentsImpl::AboutToNavigateRenderFrame( frontend_host_.reset(content::DevToolsFrontendHost::Create(new_host, this)); } -void InspectableWebContentsImpl::DidFinishLoad(content::RenderFrameHost* render_frame_host, - const GURL& validated_url) { - if (render_frame_host->GetParent()) - return; - - view_->ShowDevTools(); - - // If the devtools can dock, "SetIsDocked" will be called by devtools itself. - if (!can_dock_) - SetIsDocked(DispatchCallback(), false); -} - void InspectableWebContentsImpl::WebContentsDestroyed() { Observe(nullptr); Detach(); diff --git a/browser/inspectable_web_contents_impl.h b/browser/inspectable_web_contents_impl.h index aec9548b98a7f..249d0867daa59 100644 --- a/browser/inspectable_web_contents_impl.h +++ b/browser/inspectable_web_contents_impl.h @@ -128,8 +128,6 @@ class InspectableWebContentsImpl : // content::WebContentsObserver: void AboutToNavigateRenderFrame(content::RenderFrameHost* old_host, content::RenderFrameHost* new_host) override; - void DidFinishLoad(content::RenderFrameHost* render_frame_host, - const GURL& validated_url) override; void WebContentsDestroyed() override; // content::WebContentsDelegate: From c4cf700abd84a8dd2cd5ed381717287ec1adc58a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 5 Jun 2015 12:24:48 +0800 Subject: [PATCH 6/6] Clean up code --- browser/inspectable_web_contents.h | 21 ++++++++++++++------- browser/inspectable_web_contents_impl.cc | 20 +++++++++++++++----- browser/inspectable_web_contents_impl.h | 22 ++++++++-------------- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/browser/inspectable_web_contents.h b/browser/inspectable_web_contents.h index 7ac1366ea7c41..dc22a37cada14 100644 --- a/browser/inspectable_web_contents.h +++ b/browser/inspectable_web_contents.h @@ -3,6 +3,10 @@ #include "content/public/browser/web_contents.h" +namespace base { +class Value; +} + namespace content { class DevToolsAgentHost; } @@ -14,8 +18,7 @@ class InspectableWebContentsView; class InspectableWebContents { public: - static InspectableWebContents* Create( - const content::WebContents::CreateParams&); + static InspectableWebContents* Create(const content::WebContents::CreateParams&); // The returned InspectableWebContents takes ownership of the passed-in // WebContents. @@ -26,16 +29,20 @@ class InspectableWebContents { virtual InspectableWebContentsView* GetView() const = 0; virtual content::WebContents* GetWebContents() const = 0; + // The delegate manages its own life. + virtual void SetDelegate(InspectableWebContentsDelegate* delegate) = 0; + virtual InspectableWebContentsDelegate* GetDelegate() const = 0; + virtual void SetCanDock(bool can_dock) = 0; virtual void ShowDevTools() = 0; - // Close the DevTools completely instead of just hide it. virtual void CloseDevTools() = 0; virtual bool IsDevToolsViewShowing() = 0; virtual void AttachTo(const scoped_refptr&) = 0; - - // The delegate manages its own life. - virtual void SetDelegate(InspectableWebContentsDelegate* delegate) = 0; - virtual InspectableWebContentsDelegate* GetDelegate() const = 0; + virtual void Detach() = 0; + virtual void CallClientFunction(const std::string& function_name, + const base::Value* arg1, + const base::Value* arg2, + const base::Value* arg3) = 0; }; } // namespace brightray diff --git a/browser/inspectable_web_contents_impl.cc b/browser/inspectable_web_contents_impl.cc index 5d109e123e0bf..01f750ea02c6d 100644 --- a/browser/inspectable_web_contents_impl.cc +++ b/browser/inspectable_web_contents_impl.cc @@ -160,8 +160,8 @@ void InspectableWebContentsImpl::RegisterPrefs(PrefRegistrySimple* registry) { InspectableWebContentsImpl::InspectableWebContentsImpl( content::WebContents* web_contents) : web_contents_(web_contents), - can_dock_(true), frontend_loaded_(false), + can_dock_(true), delegate_(nullptr), weak_factory_(this) { auto context = static_cast(web_contents_->GetBrowserContext()); @@ -183,6 +183,14 @@ content::WebContents* InspectableWebContentsImpl::GetWebContents() const { return web_contents_.get(); } +void InspectableWebContentsImpl::SetDelegate(InspectableWebContentsDelegate* delegate) { + delegate_ = delegate; +} + +InspectableWebContentsDelegate* InspectableWebContentsImpl::GetDelegate() const { + return delegate_; +} + void InspectableWebContentsImpl::SetCanDock(bool can_dock) { can_dock_ = can_dock; } @@ -429,7 +437,7 @@ void InspectableWebContentsImpl::HandleMessageFromDevToolsFrontend(const std::st base::ListValue empty_params; base::ListValue* params = &empty_params; - base::DictionaryValue* dict = NULL; + base::DictionaryValue* dict = nullptr; scoped_ptr parsed_message(base::JSONReader::Read(message)); if (!parsed_message || !parsed_message->GetAsDictionary(&dict) || @@ -471,7 +479,7 @@ void InspectableWebContentsImpl::DispatchProtocolMessage( for (size_t pos = 0; pos < message.length(); pos += kMaxMessageChunkSize) { base::StringValue message_value(message.substr(pos, kMaxMessageChunkSize)); CallClientFunction("DevToolsAPI.dispatchMessageChunk", - &message_value, pos ? NULL : &total_size, NULL); + &message_value, pos ? nullptr : &total_size, nullptr); } } @@ -488,9 +496,11 @@ void InspectableWebContentsImpl::AboutToNavigateRenderFrame( } void InspectableWebContentsImpl::WebContentsDestroyed() { + frontend_loaded_ = false; Observe(nullptr); Detach(); - frontend_loaded_ = false; + agent_host_ = nullptr; + embedder_message_dispatcher_ = nullptr; for (const auto& pair : pending_requests_) delete pair.first; @@ -548,7 +558,7 @@ void InspectableWebContentsImpl::OnURLFetchComplete(const net::URLFetcher* sourc response.SetInteger("statusCode", rh ? rh->response_code() : 200); response.Set("headers", headers); - void* iterator = NULL; + void* iterator = nullptr; std::string name; std::string value; while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value)) diff --git a/browser/inspectable_web_contents_impl.h b/browser/inspectable_web_contents_impl.h index 249d0867daa59..cb7738a72b973 100644 --- a/browser/inspectable_web_contents_impl.h +++ b/browser/inspectable_web_contents_impl.h @@ -47,29 +47,23 @@ class InspectableWebContentsImpl : InspectableWebContentsView* GetView() const override; content::WebContents* GetWebContents() const override; + void SetDelegate(InspectableWebContentsDelegate* delegate) override; + InspectableWebContentsDelegate* GetDelegate() const override; void SetCanDock(bool can_dock) override; void ShowDevTools() override; void CloseDevTools() override; bool IsDevToolsViewShowing() override; void AttachTo(const scoped_refptr&) override; - - void Detach(); + void Detach() override; void CallClientFunction(const std::string& function_name, const base::Value* arg1, const base::Value* arg2, - const base::Value* arg3); + const base::Value* arg3) override; // Return the last position and size of devtools window. gfx::Rect GetDevToolsBounds() const; void SaveDevToolsBounds(const gfx::Rect& bounds); - virtual void SetDelegate(InspectableWebContentsDelegate* delegate) { - delegate_ = delegate; - } - virtual InspectableWebContentsDelegate* GetDelegate() const { - return delegate_; - } - content::WebContents* devtools_web_contents() { return devtools_web_contents_.get(); } @@ -159,17 +153,17 @@ class InspectableWebContentsImpl : scoped_ptr web_contents_; scoped_ptr devtools_web_contents_; scoped_ptr view_; + + bool frontend_loaded_; scoped_refptr agent_host_; scoped_ptr frontend_host_; + scoped_ptr embedder_message_dispatcher_; DevToolsContentsResizingStrategy contents_resizing_strategy_; gfx::Rect devtools_bounds_; bool can_dock_; - bool frontend_loaded_; - - scoped_ptr embedder_message_dispatcher_; - InspectableWebContentsDelegate* delegate_; + InspectableWebContentsDelegate* delegate_; // weak references. using PendingRequestsMap = std::map; PendingRequestsMap pending_requests_;