From 7a9892f1514a2aad235b007eb71a7b3ae8df7ce8 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 30 Oct 2017 17:06:13 +0530 Subject: [PATCH] REVIEW: Inject devtools extensions API via browser Behavior was changed in https://crbug.com/706169 --- .../devtools_embedder_message_dispatcher.cc | 2 + .../devtools_embedder_message_dispatcher.h | 2 + .../browser/inspectable_web_contents_impl.cc | 53 ++++++++++++++++--- .../browser/inspectable_web_contents_impl.h | 12 +++-- 4 files changed, 59 insertions(+), 10 deletions(-) diff --git a/brightray/browser/devtools_embedder_message_dispatcher.cc b/brightray/browser/devtools_embedder_message_dispatcher.cc index 8791bfbd2ca6..022eb6ab13b4 100644 --- a/brightray/browser/devtools_embedder_message_dispatcher.cc +++ b/brightray/browser/devtools_embedder_message_dispatcher.cc @@ -200,6 +200,8 @@ DevToolsEmbedderMessageDispatcher::CreateForDevToolsFrontend( d->RegisterHandler("setPreference", &Delegate::SetPreference, delegate); d->RegisterHandler("removePreference", &Delegate::RemovePreference, delegate); d->RegisterHandler("clearPreferences", &Delegate::ClearPreferences, delegate); + d->RegisterHandler("registerExtensionsAPI", &Delegate::RegisterExtensionsAPI, + delegate); return d; } diff --git a/brightray/browser/devtools_embedder_message_dispatcher.h b/brightray/browser/devtools_embedder_message_dispatcher.h index b77a83fc07c1..1891daf6bc8c 100644 --- a/brightray/browser/devtools_embedder_message_dispatcher.h +++ b/brightray/browser/devtools_embedder_message_dispatcher.h @@ -78,6 +78,8 @@ class DevToolsEmbedderMessageDispatcher { const std::string& value) = 0; virtual void RemovePreference(const std::string& name) = 0; virtual void ClearPreferences() = 0; + virtual void RegisterExtensionsAPI(const std::string& origin, + const std::string& script) = 0; }; using DispatchCallback = Delegate::DispatchCallback; diff --git a/brightray/browser/inspectable_web_contents_impl.cc b/brightray/browser/inspectable_web_contents_impl.cc index 31e58ee7fc63..874215f7d917 100644 --- a/brightray/browser/inspectable_web_contents_impl.cc +++ b/brightray/browser/inspectable_web_contents_impl.cc @@ -7,11 +7,13 @@ #include "brightray/browser/inspectable_web_contents_impl.h" +#include "base/guid.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram.h" #include "base/strings/pattern.h" +#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" @@ -26,6 +28,7 @@ #include "components/prefs/scoped_user_pref_update.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/host_zoom_map.h" +#include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/common/user_agent.h" @@ -597,6 +600,12 @@ void InspectableWebContentsImpl::ClearPreferences() { update.Get()->Clear(); } +void InspectableWebContentsImpl::RegisterExtensionsAPI( + const std::string& origin, + const std::string& script) { + extensions_api_[origin + "/"] = script; +} + void InspectableWebContentsImpl::HandleMessageFromDevToolsFrontend( const std::string& message) { std::string method; @@ -745,13 +754,43 @@ void InspectableWebContentsImpl::OnWebContentsFocused( #endif } -void InspectableWebContentsImpl::DidStartNavigationToPendingEntry( - const GURL& url, - content::ReloadType reload_type) { - frontend_host_.reset(content::DevToolsFrontendHost::Create( - web_contents()->GetMainFrame(), - base::Bind(&InspectableWebContentsImpl::HandleMessageFromDevToolsFrontend, - base::Unretained(this)))); +void InspectableWebContentsImpl::ReadyToCommitNavigation( + content::NavigationHandle* navigation_handle) { + if (navigation_handle->IsInMainFrame()) { + if (navigation_handle->GetRenderFrameHost() == + devtools_web_contents_->GetMainFrame() && + frontend_host_) { + return; + } + frontend_host_.reset(content::DevToolsFrontendHost::Create( + web_contents()->GetMainFrame(), + base::Bind( + &InspectableWebContentsImpl::HandleMessageFromDevToolsFrontend, + base::Unretained(this)))); + return; + } +} + +void InspectableWebContentsImpl::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + if (navigation_handle->IsInMainFrame() || + !navigation_handle->GetURL().SchemeIs("chrome-extension") || + !navigation_handle->HasCommitted()) + return; + content::RenderFrameHost* frame = navigation_handle->GetRenderFrameHost(); + auto origin = navigation_handle->GetURL().GetOrigin().spec(); + auto it = extensions_api_.find(origin); + if (it == extensions_api_.end()) + return; + // Injected Script from devtools frontend doesn't expose chrome, + // most likely bug in chromium. + base::ReplaceFirstSubstringAfterOffset(&it->second, 0, "var chrome", + "var chrome = window.chrome "); + auto script = base::StringPrintf("%s(\"%s\")", it->second.c_str(), + base::GenerateGUID().c_str()); + // Invoking content::DevToolsFrontendHost::SetupExtensionsAPI(frame, script); + // should be enough, but it seems to be a noop currently. + frame->ExecuteJavaScriptForTests(base::UTF8ToUTF16(script)); } void InspectableWebContentsImpl::OnURLFetchComplete( diff --git a/brightray/browser/inspectable_web_contents_impl.h b/brightray/browser/inspectable_web_contents_impl.h index f80b0c5bad42..c2f359bcd297 100644 --- a/brightray/browser/inspectable_web_contents_impl.h +++ b/brightray/browser/inspectable_web_contents_impl.h @@ -113,6 +113,8 @@ class InspectableWebContentsImpl : const std::string& value) override; void RemovePreference(const std::string& name) override; void ClearPreferences() override; + void RegisterExtensionsAPI(const std::string& origin, + const std::string& script) override; // content::DevToolsFrontendHostDelegate: void HandleMessageFromDevToolsFrontend(const std::string& message); @@ -129,9 +131,10 @@ class InspectableWebContentsImpl : void WebContentsDestroyed() override; void OnWebContentsFocused( content::RenderWidgetHost* render_widget_host) override; - void DidStartNavigationToPendingEntry( - const GURL& url, - content::ReloadType reload_type) override; + void ReadyToCommitNavigation( + content::NavigationHandle* navigation_handle) override; + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; // content::WebContentsDelegate: bool DidAddMessageToConsole(content::WebContents* source, @@ -192,6 +195,9 @@ class InspectableWebContentsImpl : std::unique_ptr devtools_web_contents_; std::unique_ptr view_; + using ExtensionsAPIs = std::map; + ExtensionsAPIs extensions_api_; + base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(InspectableWebContentsImpl);