diff --git a/brightray/brightray.gyp b/brightray/brightray.gyp index 4fa374b3de..a30281b1fd 100644 --- a/brightray/brightray.gyp +++ b/brightray/brightray.gyp @@ -42,6 +42,8 @@ 'browser/default_web_contents_delegate_mac.mm', 'browser/devtools_contents_resizing_strategy.cc', 'browser/devtools_contents_resizing_strategy.h', + 'browser/devtools_delegate.cc', + 'browser/devtools_delegate.h', 'browser/devtools_embedder_message_dispatcher.cc', 'browser/devtools_embedder_message_dispatcher.h', 'browser/devtools_ui.cc', diff --git a/brightray/browser/browser_main_parts.cc b/brightray/browser/browser_main_parts.cc index f5153a7845..e90a2f8a1c 100644 --- a/brightray/browser/browser_main_parts.cc +++ b/brightray/browser/browser_main_parts.cc @@ -4,8 +4,11 @@ #include "browser/browser_main_parts.h" +#include "base/command_line.h" #include "browser/browser_context.h" +#include "browser/devtools_delegate.h" #include "browser/web_ui_controller_factory.h" +#include "content/public/common/content_switches.h" #include "net/proxy/proxy_resolver_v8.h" #if defined(USE_AURA) @@ -64,6 +67,7 @@ void BrowserMainParts::PreEarlyInitialization() { InitProxyResolverV8(); } + void BrowserMainParts::ToolkitInitialized() { #if defined(USE_AURA) && defined(USE_X11) views::LinuxUI::instance()->Initialize(); @@ -94,6 +98,11 @@ void BrowserMainParts::PreMainMessageLoopRun() { new WebUIControllerFactory(browser_context_.get())); content::WebUIControllerFactory::RegisterFactory( web_ui_controller_factory_.get()); + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kRemoteDebuggingPort)) { + devtools_delegate_.reset(new brightray::DevToolsDelegate( + browser_context())); + } } void BrowserMainParts::PostMainMessageLoopRun() { diff --git a/brightray/browser/browser_main_parts.h b/brightray/browser/browser_main_parts.h index 42fd4e382b..16cf9165e1 100644 --- a/brightray/browser/browser_main_parts.h +++ b/brightray/browser/browser_main_parts.h @@ -25,6 +25,7 @@ namespace brightray { class BrowserContext; class WebUIControllerFactory; +class DevToolsDelegate; class BrowserMainParts : public content::BrowserMainParts { public: @@ -57,6 +58,7 @@ class BrowserMainParts : public content::BrowserMainParts { scoped_ptr browser_context_; scoped_ptr web_ui_controller_factory_; + scoped_ptr devtools_delegate_; #if defined(TOOLKIT_VIEWS) scoped_ptr views_delegate_; diff --git a/brightray/browser/devtools_delegate.cc b/brightray/browser/devtools_delegate.cc new file mode 100644 index 0000000000..682f06a2f4 --- /dev/null +++ b/brightray/browser/devtools_delegate.cc @@ -0,0 +1,197 @@ +// Copyright (c) 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#include "browser/devtools_delegate.h" + +#include + +#include "base/bind.h" +#include "base/command_line.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" +#include "browser/browser_context.h" +#include "browser/inspectable_web_contents.h" +#include "browser/default_web_contents_delegate.h" +#include "browser/inspectable_web_contents_delegate.h" +#include "content/public/browser/devtools_agent_host.h" +#include "content/public/browser/devtools_http_handler.h" +#include "content/public/browser/devtools_target.h" +#include "content/public/browser/favicon_status.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/content_switches.h" +#include "content/public/common/url_constants.h" +#include "content/public/common/user_agent.h" +#include "net/socket/tcp_listen_socket.h" +#include "ui/base/resource/resource_bundle.h" + +using content::DevToolsAgentHost; +using content::RenderViewHost; +using content::WebContents; +using content::BrowserContext; +using content::DevToolsTarget; +using content::DevToolsHttpHandler; + +namespace { + +// A hack here: +// Copy from grit/shell_resources.h of chromium repository +// since libcontentchromium doesn't expose content_shell resources. +const int kIDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE = 25500; + +const char kTargetTypePage[] = "page"; + +net::StreamListenSocketFactory* CreateSocketFactory() { + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + // See if the user specified a port on the command line (useful for + // automation). If not, use an ephemeral port by specifying 0. + int port = 0; + if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) { + int temp_port; + std::string port_str = + command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort); + if (base::StringToInt(port_str, &temp_port) && + temp_port > 0 && temp_port < 65535) { + port = temp_port; + } else { + DLOG(WARNING) << "Invalid http debugger port number " << temp_port; + } + } + return new net::TCPListenSocketFactory("127.0.0.1", port); +} + +class Target : public content::DevToolsTarget { + public: + explicit Target(WebContents* web_contents); + + virtual std::string GetId() const OVERRIDE { return id_; } + virtual std::string GetType() const OVERRIDE { return kTargetTypePage; } + virtual std::string GetTitle() const OVERRIDE { return title_; } + virtual std::string GetDescription() const OVERRIDE { return std::string(); } + virtual GURL GetURL() const OVERRIDE { return url_; } + virtual GURL GetFaviconURL() const OVERRIDE { return favicon_url_; } + virtual base::TimeTicks GetLastActivityTime() const OVERRIDE { + return last_activity_time_; + } + virtual bool IsAttached() const OVERRIDE { + return agent_host_->IsAttached(); + } + virtual scoped_refptr GetAgentHost() const OVERRIDE { + return agent_host_; + } + virtual bool Activate() const OVERRIDE; + virtual bool Close() const OVERRIDE; + + private: + scoped_refptr agent_host_; + std::string id_; + std::string title_; + GURL url_; + GURL favicon_url_; + base::TimeTicks last_activity_time_; +}; + +Target::Target(WebContents* web_contents) { + agent_host_ = + DevToolsAgentHost::GetOrCreateFor(web_contents->GetRenderViewHost()); + id_ = agent_host_->GetId(); + title_ = base::UTF16ToUTF8(web_contents->GetTitle()); + url_ = web_contents->GetURL(); + content::NavigationController& controller = web_contents->GetController(); + content::NavigationEntry* entry = controller.GetActiveEntry(); + if (entry != NULL && entry->GetURL().is_valid()) + favicon_url_ = entry->GetFavicon().url; + last_activity_time_ = web_contents->GetLastActiveTime(); +} + +bool Target::Activate() const { + RenderViewHost* rvh = agent_host_->GetRenderViewHost(); + if (!rvh) + return false; + WebContents* web_contents = WebContents::FromRenderViewHost(rvh); + if (!web_contents) + return false; + web_contents->GetDelegate()->ActivateContents(web_contents); + return true; +} + +bool Target::Close() const { + RenderViewHost* rvh = agent_host_->GetRenderViewHost(); + if (!rvh) + return false; + rvh->ClosePage(); + return true; +} + +} // namespace + +namespace brightray { + +DevToolsDelegate::DevToolsDelegate( + content::BrowserContext* browser_context) + : browser_context_(browser_context) { + std::string frontend_url; + devtools_http_handler_ = + DevToolsHttpHandler::Start(CreateSocketFactory(), frontend_url, this); +} + +DevToolsDelegate::~DevToolsDelegate() { + LOG(ERROR) << "delete!"; +} + +void DevToolsDelegate::Stop() { + // The call below destroys this. + devtools_http_handler_->Stop(); +} + +std::string DevToolsDelegate::GetDiscoveryPageHTML() { + return ResourceBundle::GetSharedInstance().GetRawDataResource( + kIDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE).as_string(); +} + +bool DevToolsDelegate::BundlesFrontendResources() { + return true; +} + +base::FilePath DevToolsDelegate::GetDebugFrontendDir() { + return base::FilePath(); +} + +std::string DevToolsDelegate::GetPageThumbnailData(const GURL& url) { + return std::string(); +} + +scoped_ptr +DevToolsDelegate::CreateNewTarget(const GURL& url) { + content::WebContents::CreateParams create_params( + new brightray::BrowserContext()); + brightray::InspectableWebContents* web_contents = + brightray::InspectableWebContents::Create(create_params); + web_contents->SetDelegate(new brightray::InspectableWebContentsDelegate()); + return scoped_ptr(new Target(web_contents->GetWebContents())); +} + +void DevToolsDelegate::EnumerateTargets(TargetCallback callback) { + TargetList targets; + std::vector rvh_list = + content::DevToolsAgentHost::GetValidRenderViewHosts(); + for (std::vector::iterator it = rvh_list.begin(); + it != rvh_list.end(); ++it) { + WebContents* web_contents = WebContents::FromRenderViewHost(*it); + if (web_contents) + targets.push_back(new Target(web_contents)); + } + callback.Run(targets); +} + +scoped_ptr +DevToolsDelegate::CreateSocketForTethering( + net::StreamListenSocket::Delegate* delegate, + std::string* name) { + return scoped_ptr(); +} + +} // namespace brightray diff --git a/brightray/browser/devtools_delegate.h b/brightray/browser/devtools_delegate.h new file mode 100644 index 0000000000..5c8580a625 --- /dev/null +++ b/brightray/browser/devtools_delegate.h @@ -0,0 +1,54 @@ +// Copyright (c) 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#ifndef BRIGHTRAY_DEVTOOLS_DELEGATE_H_ +#define BRIGHTRAY_DEVTOOLS_DELEGATE_H_ + +#include + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "content/public/browser/devtools_http_handler_delegate.h" + +namespace content { +class BrowserContext; +class DevToolsHttpHandler; +} + +namespace brightray { + +class DevToolsDelegate : public content::DevToolsHttpHandlerDelegate { + public: + explicit DevToolsDelegate(content::BrowserContext* browser_context); + virtual ~DevToolsDelegate(); + + // Stops http server. + void Stop(); + + // DevToolsHttpProtocolHandler::Delegate overrides. + virtual std::string GetDiscoveryPageHTML() OVERRIDE; + virtual bool BundlesFrontendResources() OVERRIDE; + virtual base::FilePath GetDebugFrontendDir() OVERRIDE; + virtual std::string GetPageThumbnailData(const GURL& url) OVERRIDE; + virtual scoped_ptr CreateNewTarget( + const GURL& url) OVERRIDE; + virtual void EnumerateTargets(TargetCallback callback) OVERRIDE; + virtual scoped_ptr CreateSocketForTethering( + net::StreamListenSocket::Delegate* delegate, + std::string* name) OVERRIDE; + + content::DevToolsHttpHandler* devtools_http_handler() { + return devtools_http_handler_; + } + + private: + content::BrowserContext* browser_context_; + content::DevToolsHttpHandler* devtools_http_handler_; + + DISALLOW_COPY_AND_ASSIGN(DevToolsDelegate); +}; + +} // namespace brightray + +#endif // BRIGHTRAY_DEVTOOLS_DELEGATE_H_