summaryrefslogtreecommitdiffstats
path: root/chromecast
diff options
context:
space:
mode:
authorgunsch@chromium.org <gunsch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-15 05:49:27 +0000
committergunsch@chromium.org <gunsch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-15 05:50:38 +0000
commitdba26a7c39247f4744151434fc985e3d73885326 (patch)
tree39797126b6db33d2baa7b00b10ede339bb1049a2 /chromecast
parentae58dcec09dbc814f48f65b40b64a2d68edce764 (diff)
downloadchromium_src-dba26a7c39247f4744151434fc985e3d73885326.zip
chromium_src-dba26a7c39247f4744151434fc985e3d73885326.tar.gz
chromium_src-dba26a7c39247f4744151434fc985e3d73885326.tar.bz2
Adds remote devtools support to cast_shell.
This is based largely on ShellDevtoolsDelegate, but is enabled/disabled conditionally based on a preference value that can be controlled by the cast receiver. R=damienv@chromium.org,lcwu@chromium.org,byungchul@chromium.org BUG=400919 Review URL: https://codereview.chromium.org/454063004 Cr-Commit-Position: refs/heads/master@{#289812} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289812 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromecast')
-rw-r--r--chromecast/DEPS1
-rw-r--r--chromecast/chromecast.gyp26
-rw-r--r--chromecast/common/chromecast_config.cc2
-rw-r--r--chromecast/common/pref_names.cc13
-rw-r--r--chromecast/common/pref_names.h14
-rw-r--r--chromecast/shell/browser/cast_browser_main_parts.cc8
-rw-r--r--chromecast/shell/browser/cast_browser_main_parts.h3
-rw-r--r--chromecast/shell/browser/devtools/cast_dev_tools_delegate.cc150
-rw-r--r--chromecast/shell/browser/devtools/cast_dev_tools_delegate.h42
-rw-r--r--chromecast/shell/browser/devtools/remote_debugging_server.cc116
-rw-r--r--chromecast/shell/browser/devtools/remote_debugging_server.h41
-rw-r--r--chromecast/shell/browser/devtools/remote_debugging_server_simple.cc15
-rw-r--r--chromecast/shell/browser/resources/resource_ids22
-rw-r--r--chromecast/shell/browser/resources/shell_devtools_discovery_page.html56
-rw-r--r--chromecast/shell/browser/resources/shell_resources.grd16
15 files changed, 523 insertions, 2 deletions
diff --git a/chromecast/DEPS b/chromecast/DEPS
index 1a7a778..203b08d 100644
--- a/chromecast/DEPS
+++ b/chromecast/DEPS
@@ -3,6 +3,7 @@
include_rules = [
"+content/public/common",
"+crypto",
+ "+grit/shell_resources.h",
"+net",
"+ui",
]
diff --git a/chromecast/chromecast.gyp b/chromecast/chromecast.gyp
index ecc1dc6..4ec7656 100644
--- a/chromecast/chromecast.gyp
+++ b/chromecast/chromecast.gyp
@@ -24,6 +24,8 @@
'common/cast_paths.h',
'common/chromecast_config.cc',
'common/chromecast_config.h',
+ 'common/pref_names.cc',
+ 'common/pref_names.h',
],
'conditions': [
['chromecast_branding=="Chrome"', {
@@ -67,7 +69,20 @@
{
'target_name': 'cast_shell_resources',
'type': 'none',
- # Place holder for cast_shell specific resources.
+ 'variables': {
+ 'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/chromecast',
+ },
+ 'actions': [
+ {
+ 'action_name': 'cast_shell_resources',
+ 'variables': {
+ 'grit_grd_file': 'shell/browser/resources/shell_resources.grd',
+ 'grit_resource_ids': 'shell/browser/resources/resource_ids',
+ },
+ 'includes': [ '../build/grit_action.gypi' ],
+ },
+ ],
+ 'includes': [ '../build/grit_target.gypi' ],
},
{
'target_name': 'cast_shell_pak',
@@ -89,6 +104,7 @@
'variables': {
'pak_inputs': [
'<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/blink_resources.pak',
+ '<(SHARED_INTERMEDIATE_DIR)/chromecast/shell_resources.pak',
'<(SHARED_INTERMEDIATE_DIR)/content/content_resources.pak',
'<(SHARED_INTERMEDIATE_DIR)/content/app/strings/content_strings_en-US.pak',
'<(SHARED_INTERMEDIATE_DIR)/net/net_resources.pak',
@@ -112,6 +128,7 @@
'cast_common',
'cast_service',
'cast_shell_pak',
+ 'cast_shell_resources',
'cast_version_header',
'../ui/aura/aura.gyp:aura_test_support',
'../content/content.gyp:content',
@@ -134,6 +151,10 @@
'shell/browser/cast_content_browser_client.h',
'shell/browser/cast_http_user_agent_settings.cc',
'shell/browser/cast_http_user_agent_settings.h',
+ 'shell/browser/devtools/cast_dev_tools_delegate.cc',
+ 'shell/browser/devtools/cast_dev_tools_delegate.h',
+ 'shell/browser/devtools/remote_debugging_server.cc',
+ 'shell/browser/devtools/remote_debugging_server.h',
'shell/browser/geolocation/cast_access_token_store.cc',
'shell/browser/geolocation/cast_access_token_store.h',
'shell/browser/url_request_context_factory.cc',
@@ -152,6 +173,9 @@
'dependencies': [
'../ui/ozone/ozone.gyp:eglplatform_shim_x11',
],
+ 'sources': [
+ 'shell/browser/devtools/remote_debugging_server_simple.cc',
+ ],
}],
],
},
diff --git a/chromecast/common/chromecast_config.cc b/chromecast/common/chromecast_config.cc
index f016a68..dfb3866 100644
--- a/chromecast/common/chromecast_config.cc
+++ b/chromecast/common/chromecast_config.cc
@@ -16,6 +16,7 @@
#include "base/prefs/pref_store.h"
#include "base/strings/string_number_conversions.h"
#include "chromecast/common/cast_paths.h"
+#include "chromecast/common/pref_names.h"
namespace chromecast {
@@ -71,6 +72,7 @@ ChromecastConfig::~ChromecastConfig() {
bool ChromecastConfig::Load(PrefRegistrySimple* registry) {
DCHECK(thread_checker_.CalledOnValidThread());
VLOG(1) << "Loading config from " << config_path_.value();
+ registry->RegisterIntegerPref(prefs::kRemoteDebuggingPort, 0);
RegisterPlatformPrefs(registry);
diff --git a/chromecast/common/pref_names.cc b/chromecast/common/pref_names.cc
new file mode 100644
index 0000000..0fed7c8
--- /dev/null
+++ b/chromecast/common/pref_names.cc
@@ -0,0 +1,13 @@
+// Copyright 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 file.
+
+#include "chromecast/common/pref_names.h"
+
+namespace prefs {
+
+// Port on which to host the remote debugging server. A value of 0 indicates
+// that remote debugging is disabled.
+const char kRemoteDebuggingPort[] = "remote_debugging_port";
+
+} // namespace prefs
diff --git a/chromecast/common/pref_names.h b/chromecast/common/pref_names.h
new file mode 100644
index 0000000..669f19d
--- /dev/null
+++ b/chromecast/common/pref_names.h
@@ -0,0 +1,14 @@
+// Copyright 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 file.
+
+#ifndef CHROMECAST_COMMON_PREF_NAMES_H_
+#define CHROMECAST_COMMON_PREF_NAMES_H_
+
+namespace prefs {
+
+extern const char kRemoteDebuggingPort[];
+
+} // namespace prefs
+
+#endif // CHROMECAST_COMMON_PREF_NAMES_H_
diff --git a/chromecast/shell/browser/cast_browser_main_parts.cc b/chromecast/shell/browser/cast_browser_main_parts.cc
index 1da0937..d1a82c2 100644
--- a/chromecast/shell/browser/cast_browser_main_parts.cc
+++ b/chromecast/shell/browser/cast_browser_main_parts.cc
@@ -5,10 +5,13 @@
#include "chromecast/shell/browser/cast_browser_main_parts.h"
#include "base/command_line.h"
+#include "base/prefs/pref_registry_simple.h"
+#include "chromecast/common/chromecast_config.h"
#include "chromecast/net/network_change_notifier_cast.h"
#include "chromecast/net/network_change_notifier_factory_cast.h"
#include "chromecast/service/cast_service.h"
#include "chromecast/shell/browser/cast_browser_context.h"
+#include "chromecast/shell/browser/devtools/remote_debugging_server.h"
#include "chromecast/shell/browser/url_request_context_factory.h"
namespace chromecast {
@@ -62,6 +65,7 @@ void CastBrowserMainParts::PostMainMessageLoopStart() {
}
int CastBrowserMainParts::PreCreateThreads() {
+ ChromecastConfig::Create(new PrefRegistrySimple());
return 0;
}
@@ -69,6 +73,7 @@ void CastBrowserMainParts::PreMainMessageLoopRun() {
url_request_context_factory_->InitializeOnUIThread();
browser_context_.reset(new CastBrowserContext(url_request_context_factory_));
+ dev_tools_.reset(new RemoteDebuggingServer());
cast_service_.reset(CastService::Create(browser_context_.get()));
cast_service_->Start();
@@ -81,6 +86,9 @@ bool CastBrowserMainParts::MainMessageLoopRun(int* result_code) {
void CastBrowserMainParts::PostMainMessageLoopRun() {
cast_service_->Stop();
+
+ cast_service_.reset();
+ dev_tools_.reset();
browser_context_.reset();
}
diff --git a/chromecast/shell/browser/cast_browser_main_parts.h b/chromecast/shell/browser/cast_browser_main_parts.h
index 50e4ee2..988ceea 100644
--- a/chromecast/shell/browser/cast_browser_main_parts.h
+++ b/chromecast/shell/browser/cast_browser_main_parts.h
@@ -21,6 +21,7 @@ class CastService;
namespace shell {
class CastBrowserContext;
+class RemoteDebuggingServer;
class URLRequestContextFactory;
class CastBrowserMainParts : public content::BrowserMainParts {
@@ -45,9 +46,9 @@ class CastBrowserMainParts : public content::BrowserMainParts {
private:
scoped_ptr<CastBrowserContext> browser_context_;
scoped_ptr<CastService> cast_service_;
+ scoped_ptr<RemoteDebuggingServer> dev_tools_;
URLRequestContextFactory* const url_request_context_factory_;
-
DISALLOW_COPY_AND_ASSIGN(CastBrowserMainParts);
};
diff --git a/chromecast/shell/browser/devtools/cast_dev_tools_delegate.cc b/chromecast/shell/browser/devtools/cast_dev_tools_delegate.cc
new file mode 100644
index 0000000..77cfba1
--- /dev/null
+++ b/chromecast/shell/browser/devtools/cast_dev_tools_delegate.cc
@@ -0,0 +1,150 @@
+// Copyright 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 file.
+
+#include "chromecast/shell/browser/devtools/cast_dev_tools_delegate.h"
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/public/browser/devtools_agent_host.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/browser/web_contents_delegate.h"
+#include "grit/shell_resources.h"
+#include "ui/base/resource/resource_bundle.h"
+
+namespace chromecast {
+namespace shell {
+
+namespace {
+
+const char kTargetTypePage[] = "page";
+
+class Target : public content::DevToolsTarget {
+ public:
+ explicit Target(content::WebContents* web_contents);
+
+ virtual std::string GetId() const OVERRIDE { return id_; }
+ virtual std::string GetParentId() const OVERRIDE { return std::string(); }
+ 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<content::DevToolsAgentHost> GetAgentHost()
+ const OVERRIDE {
+ return agent_host_;
+ }
+ virtual bool Activate() const OVERRIDE;
+ virtual bool Close() const OVERRIDE;
+
+ private:
+ scoped_refptr<content::DevToolsAgentHost> agent_host_;
+ std::string id_;
+ std::string title_;
+ GURL url_;
+ GURL favicon_url_;
+ base::TimeTicks last_activity_time_;
+
+ DISALLOW_COPY_AND_ASSIGN(Target);
+};
+
+Target::Target(content::WebContents* web_contents) {
+ agent_host_ = content::DevToolsAgentHost::GetOrCreateFor(web_contents);
+ 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 {
+ content::WebContents* web_contents = agent_host_->GetWebContents();
+ if (!web_contents)
+ return false;
+ web_contents->GetDelegate()->ActivateContents(web_contents);
+ return true;
+}
+
+bool Target::Close() const {
+ content::WebContents* web_contents = agent_host_->GetWebContents();
+ if (!web_contents)
+ return false;
+ web_contents->GetRenderViewHost()->ClosePage();
+ return true;
+}
+
+} // namespace
+
+CastDevToolsDelegate::CastDevToolsDelegate() {
+}
+
+CastDevToolsDelegate::~CastDevToolsDelegate() {
+}
+
+std::string CastDevToolsDelegate::GetDiscoveryPageHTML() {
+#if defined(OS_ANDROID)
+ return std::string();
+#else
+ return ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_CAST_SHELL_DEVTOOLS_DISCOVERY_PAGE).as_string();
+#endif // defined(OS_ANDROID)
+}
+
+bool CastDevToolsDelegate::BundlesFrontendResources() {
+#if defined(OS_ANDROID)
+ // Since Android remote debugging connects over a Unix domain socket, Chrome
+ // will not load the same homepage.
+ return false;
+#else
+ return true;
+#endif // defined(OS_ANDROID)
+}
+
+base::FilePath CastDevToolsDelegate::GetDebugFrontendDir() {
+ return base::FilePath();
+}
+
+std::string CastDevToolsDelegate::GetPageThumbnailData(const GURL& url) {
+ return "";
+}
+
+scoped_ptr<content::DevToolsTarget> CastDevToolsDelegate::CreateNewTarget(
+ const GURL& url) {
+ return scoped_ptr<content::DevToolsTarget>();
+}
+
+void CastDevToolsDelegate::EnumerateTargets(TargetCallback callback) {
+ TargetList targets;
+ std::vector<content::WebContents*> wc_list =
+ content::DevToolsAgentHost::GetInspectableWebContents();
+ for (std::vector<content::WebContents*>::iterator it = wc_list.begin();
+ it != wc_list.end();
+ ++it) {
+ targets.push_back(new Target(*it));
+ }
+ callback.Run(targets);
+}
+
+scoped_ptr<net::StreamListenSocket>
+CastDevToolsDelegate::CreateSocketForTethering(
+ net::StreamListenSocket::Delegate* delegate,
+ std::string* name) {
+ return scoped_ptr<net::StreamListenSocket>();
+}
+
+} // namespace shell
+} // namespace chromecast
diff --git a/chromecast/shell/browser/devtools/cast_dev_tools_delegate.h b/chromecast/shell/browser/devtools/cast_dev_tools_delegate.h
new file mode 100644
index 0000000..e41e1a8
--- /dev/null
+++ b/chromecast/shell/browser/devtools/cast_dev_tools_delegate.h
@@ -0,0 +1,42 @@
+// Copyright 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 file.
+
+#ifndef CHROMECAST_SHELL_BROWSER_DEVTOOLS_CAST_DEV_TOOLS_DELEGATE_H_
+#define CHROMECAST_SHELL_BROWSER_DEVTOOLS_CAST_DEV_TOOLS_DELEGATE_H_
+
+#include "content/public/browser/devtools_http_handler_delegate.h"
+#include "net/socket/stream_listen_socket.h"
+
+namespace base {
+class FilePath;
+}
+
+namespace chromecast {
+namespace shell {
+
+class CastDevToolsDelegate : public content::DevToolsHttpHandlerDelegate {
+ public:
+ CastDevToolsDelegate();
+ virtual ~CastDevToolsDelegate();
+
+ // DevToolsHttpHandlerDelegate implementation.
+ 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<content::DevToolsTarget> CreateNewTarget(
+ const GURL& url) OVERRIDE;
+ virtual void EnumerateTargets(TargetCallback callback) OVERRIDE;
+ virtual scoped_ptr<net::StreamListenSocket> CreateSocketForTethering(
+ net::StreamListenSocket::Delegate* delegate,
+ std::string* name) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CastDevToolsDelegate);
+};
+
+} // namespace shell
+} // namespace chromecast
+
+#endif // CHROMECAST_SHELL_BROWSER_DEVTOOLS_CAST_DEV_TOOLS_DELEGATE_H_
diff --git a/chromecast/shell/browser/devtools/remote_debugging_server.cc b/chromecast/shell/browser/devtools/remote_debugging_server.cc
new file mode 100644
index 0000000..076b066
--- /dev/null
+++ b/chromecast/shell/browser/devtools/remote_debugging_server.cc
@@ -0,0 +1,116 @@
+// Copyright 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 file.
+
+#include "chromecast/shell/browser/devtools/remote_debugging_server.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/strings/stringprintf.h"
+#include "chromecast/common/chromecast_config.h"
+#include "chromecast/common/pref_names.h"
+#include "chromecast/shell/browser/devtools/cast_dev_tools_delegate.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/devtools_http_handler.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/user_agent.h"
+#include "net/socket/tcp_listen_socket.h"
+
+#if defined(OS_ANDROID)
+#include "content/public/browser/android/devtools_auth.h"
+#include "net/socket/unix_domain_socket_posix.h"
+#endif // defined(OS_ANDROID)
+
+namespace chromecast {
+namespace shell {
+
+namespace {
+
+#if defined(OS_ANDROID)
+const char kFrontEndURL[] =
+ "http://chrome-devtools-frontend.appspot.com/serve_rev/%s/devtools.html";
+#endif // defined(OS_ANDROID)
+const int kDefaultRemoteDebuggingPort = 9222;
+
+net::StreamListenSocketFactory* CreateSocketFactory(int port) {
+#if defined(OS_ANDROID)
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ std::string socket_name = "content_shell_devtools_remote";
+ if (command_line->HasSwitch(switches::kRemoteDebuggingSocketName)) {
+ socket_name = command_line->GetSwitchValueASCII(
+ switches::kRemoteDebuggingSocketName);
+ }
+ return new net::UnixDomainSocketWithAbstractNamespaceFactory(
+ socket_name, "", base::Bind(&content::CanUserConnectToDevTools));
+#else
+ return new net::TCPListenSocketFactory("0.0.0.0", port);
+#endif // defined(OS_ANDROID)
+}
+
+std::string GetFrontendUrl() {
+#if defined(OS_ANDROID)
+ return base::StringPrintf(kFrontEndURL, content::GetWebKitRevision().c_str());
+#else
+ return std::string();
+#endif // defined(OS_ANDROID)
+}
+
+} // namespace
+
+RemoteDebuggingServer::RemoteDebuggingServer()
+ : devtools_http_handler_(NULL),
+ port_(0) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ pref_port_.Init(prefs::kRemoteDebuggingPort,
+ ChromecastConfig::GetInstance()->pref_service(),
+ base::Bind(&RemoteDebuggingServer::OnPortChanged,
+ base::Unretained(this)));
+
+ // Starts new dev tools, clearing port number saved in config.
+ // Remote debugging in production must be triggered only by config server.
+ pref_port_.SetValue(ShouldStartImmediately() ?
+ kDefaultRemoteDebuggingPort : 0);
+ OnPortChanged();
+}
+
+RemoteDebuggingServer::~RemoteDebuggingServer() {
+ pref_port_.SetValue(0);
+ OnPortChanged();
+}
+
+void RemoteDebuggingServer::OnPortChanged() {
+ int new_port = *pref_port_;
+ if (new_port < 0) {
+ new_port = 0;
+ }
+ VLOG(1) << "OnPortChanged called: old_port=" << port_
+ << ", new_port=" << new_port;
+
+ if (new_port == port_) {
+ VLOG(1) << "Port has not been changed. Ignore silently.";
+ return;
+ }
+
+ if (devtools_http_handler_) {
+ LOG(INFO) << "Stop old devtools: port=" << port_;
+ // Note: Stop destroys devtools_http_handler_.
+ devtools_http_handler_->Stop();
+ devtools_http_handler_ = NULL;
+ }
+
+ port_ = new_port;
+ if (port_ > 0) {
+ devtools_http_handler_ = content::DevToolsHttpHandler::Start(
+ CreateSocketFactory(port_),
+ GetFrontendUrl(),
+ new CastDevToolsDelegate(),
+ base::FilePath());
+ LOG(INFO) << "Devtools started: port=" << port_;
+ }
+}
+
+} // namespace shell
+} // namespace chromecast
diff --git a/chromecast/shell/browser/devtools/remote_debugging_server.h b/chromecast/shell/browser/devtools/remote_debugging_server.h
new file mode 100644
index 0000000..f4351fa
--- /dev/null
+++ b/chromecast/shell/browser/devtools/remote_debugging_server.h
@@ -0,0 +1,41 @@
+// Copyright 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 file.
+
+#ifndef CHROMECAST_SHELL_BROWSER_DEVTOOLS_REMOTE_DEBUGGING_SERVER_H_
+#define CHROMECAST_SHELL_BROWSER_DEVTOOLS_REMOTE_DEBUGGING_SERVER_H_
+
+#include "base/prefs/pref_member.h"
+
+namespace content {
+class DevToolsHttpHandler;
+} // namespace content
+
+namespace chromecast {
+namespace shell {
+
+class RemoteDebuggingServer {
+ public:
+ RemoteDebuggingServer();
+ ~RemoteDebuggingServer();
+
+ private:
+ // Called on port number changed.
+ void OnPortChanged();
+
+ // Returns whether or not the remote debugging server should be available
+ // on device startup.
+ bool ShouldStartImmediately();
+
+ content::DevToolsHttpHandler* devtools_http_handler_;
+
+ IntegerPrefMember pref_port_;
+ int port_;
+
+ DISALLOW_COPY_AND_ASSIGN(RemoteDebuggingServer);
+};
+
+} // namespace shell
+} // namespace chromecast
+
+#endif // CHROMECAST_SHELL_BROWSER_DEVTOOLS_REMOTE_DEBUGGING_SERVER_H_
diff --git a/chromecast/shell/browser/devtools/remote_debugging_server_simple.cc b/chromecast/shell/browser/devtools/remote_debugging_server_simple.cc
new file mode 100644
index 0000000..40d7a2c
--- /dev/null
+++ b/chromecast/shell/browser/devtools/remote_debugging_server_simple.cc
@@ -0,0 +1,15 @@
+// Copyright 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 file.
+
+#include "chromecast/shell/browser/devtools/remote_debugging_server.h"
+
+namespace chromecast {
+namespace shell {
+
+bool RemoteDebuggingServer::ShouldStartImmediately() {
+ return true;
+}
+
+} // namespace shell
+} // namespace chromecast
diff --git a/chromecast/shell/browser/resources/resource_ids b/chromecast/shell/browser/resources/resource_ids
new file mode 100644
index 0000000..e0bce0d
--- /dev/null
+++ b/chromecast/shell/browser/resources/resource_ids
@@ -0,0 +1,22 @@
+# Copyright 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 file.
+#
+# This file is used to assign starting resource ids for resources and strings
+# used by Chromium. This is done to ensure that resource ids are unique
+# across all the grd files. If you are adding a new grd file, please add
+# a new entry to this file.
+#
+# The first entry in the file, SRCDIR, is special: It is a relative path from
+# this file to the base of your checkout.
+#
+# http://msdn.microsoft.com/en-us/library/t2zechd4(VS.71).aspx says that the
+# range for IDR_ is 1 to 28,671 and the range for IDS_ is 1 to 32,767 and
+# common convention starts practical use of IDs at 100 or 101.
+{
+ "SRCDIR": "../../../..",
+
+ "chromecast/shell/browser/resources/shell_resources.grd": {
+ "includes": [31000],
+ },
+}
diff --git a/chromecast/shell/browser/resources/shell_devtools_discovery_page.html b/chromecast/shell/browser/resources/shell_devtools_discovery_page.html
new file mode 100644
index 0000000..00c9374
--- /dev/null
+++ b/chromecast/shell/browser/resources/shell_devtools_discovery_page.html
@@ -0,0 +1,56 @@
+<html>
+<head>
+<title>Cast shell remote debugging</title>
+<style>
+</style>
+
+<script>
+function onLoad() {
+ var tabs_list_request = new XMLHttpRequest();
+ tabs_list_request.open("GET", "/json/list?t=" + new Date().getTime(), true);
+ tabs_list_request.onreadystatechange = onReady;
+ tabs_list_request.send();
+}
+
+function onReady() {
+ if(this.readyState == 4 && this.status == 200) {
+ if(this.response != null) {
+ var responseJSON = JSON.parse(this.response);
+ for (var i = 0; i < responseJSON.length; ++i) {
+ appendItem(responseJSON[i]);
+ }
+ }
+ }
+}
+
+function appendItem(item_object) {
+ var frontend_ref;
+ if (item_object.devtoolsFrontendUrl) {
+ frontend_ref = document.createElement("a");
+ frontend_ref.href = item_object.devtoolsFrontendUrl;
+ frontend_ref.title = item_object.title;
+ } else {
+ frontend_ref = document.createElement("div");
+ frontend_ref.title = "The tab already has active debugging session";
+ }
+
+ var text = document.createElement("div");
+ if (item_object.title)
+ text.innerText = item_object.title;
+ else
+ text.innerText = "(untitled tab)";
+ text.style.cssText = "background-image:url(" + item_object.faviconUrl + ")";
+ frontend_ref.appendChild(text);
+
+ var item = document.createElement("p");
+ item.appendChild(frontend_ref);
+
+ document.getElementById("items").appendChild(item);
+}
+</script>
+</head>
+<body onload='onLoad()'>
+ <div id='caption'>Inspectable WebContents</div>
+ <div id='items'></div>
+</body>
+</html>
diff --git a/chromecast/shell/browser/resources/shell_resources.grd b/chromecast/shell/browser/resources/shell_resources.grd
new file mode 100644
index 0000000..9d4c322
--- /dev/null
+++ b/chromecast/shell/browser/resources/shell_resources.grd
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grit latest_public_release="0" current_release="1">
+ <outputs>
+ <output filename="grit/shell_resources.h" type="rc_header">
+ <emit emit_type='prepend'></emit>
+ </output>
+ <output filename="shell_resources.pak" type="data_package" />
+ <output filename="shell_resources.rc" type="rc_all" />
+ </outputs>
+ <translations />
+ <release seq="1">
+ <includes>
+ <include name="IDR_CAST_SHELL_DEVTOOLS_DISCOVERY_PAGE" file="shell_devtools_discovery_page.html" type="BINDATA" />
+ </includes>
+ </release>
+</grit>