1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromecast/browser/devtools/remote_debugging_server.h"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/strings/stringprintf.h"
12 #include "chromecast/browser/devtools/cast_dev_tools_delegate.h"
13 #include "chromecast/common/chromecast_config.h"
14 #include "chromecast/common/pref_names.h"
15 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/devtools_http_handler.h"
18 #include "content/public/common/content_switches.h"
19 #include "content/public/common/user_agent.h"
20 #include "net/socket/tcp_server_socket.h"
22 #if defined(OS_ANDROID)
23 #include "content/public/browser/android/devtools_auth.h"
24 #include "net/socket/unix_domain_server_socket_posix.h"
25 #endif // defined(OS_ANDROID)
27 namespace chromecast {
32 const char kFrontEndURL[] =
33 "https://chrome-devtools-frontend.appspot.com/serve_rev/%s/devtools.html";
34 const int kDefaultRemoteDebuggingPort = 9222;
36 #if defined(OS_ANDROID)
37 class UnixDomainServerSocketFactory
38 : public content::DevToolsHttpHandler::ServerSocketFactory {
40 explicit UnixDomainServerSocketFactory(const std::string& socket_name)
41 : content::DevToolsHttpHandler::ServerSocketFactory(socket_name, 0, 1) {}
44 // content::DevToolsHttpHandler::ServerSocketFactory.
45 virtual scoped_ptr<net::ServerSocket> Create() const override {
46 return scoped_ptr<net::ServerSocket>(
47 new net::UnixDomainServerSocket(
48 base::Bind(&content::CanUserConnectToDevTools),
49 true /* use_abstract_namespace */));
52 DISALLOW_COPY_AND_ASSIGN(UnixDomainServerSocketFactory);
55 class TCPServerSocketFactory
56 : public content::DevToolsHttpHandler::ServerSocketFactory {
58 TCPServerSocketFactory(const std::string& address, int port, int backlog)
59 : content::DevToolsHttpHandler::ServerSocketFactory(
60 address, port, backlog) {}
63 // content::DevToolsHttpHandler::ServerSocketFactory.
64 virtual scoped_ptr<net::ServerSocket> Create() const override {
65 return scoped_ptr<net::ServerSocket>(
66 new net::TCPServerSocket(NULL, net::NetLog::Source()));
69 DISALLOW_COPY_AND_ASSIGN(TCPServerSocketFactory);
73 scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory>
74 CreateSocketFactory(int port) {
75 #if defined(OS_ANDROID)
76 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
77 std::string socket_name = "cast_shell_devtools_remote";
78 if (command_line->HasSwitch(switches::kRemoteDebuggingSocketName)) {
79 socket_name = command_line->GetSwitchValueASCII(
80 switches::kRemoteDebuggingSocketName);
82 return scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory>(
83 new UnixDomainServerSocketFactory(socket_name));
85 return scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory>(
86 new TCPServerSocketFactory("0.0.0.0", port, 1));
90 std::string GetFrontendUrl() {
91 return base::StringPrintf(kFrontEndURL, content::GetWebKitRevision().c_str());
96 RemoteDebuggingServer::RemoteDebuggingServer()
97 : devtools_http_handler_(NULL),
99 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
100 pref_port_.Init(prefs::kRemoteDebuggingPort,
101 ChromecastConfig::GetInstance()->pref_service(),
102 base::Bind(&RemoteDebuggingServer::OnPortChanged,
103 base::Unretained(this)));
105 // Starts new dev tools, clearing port number saved in config.
106 // Remote debugging in production must be triggered only by config server.
107 pref_port_.SetValue(ShouldStartImmediately() ?
108 kDefaultRemoteDebuggingPort : 0);
112 RemoteDebuggingServer::~RemoteDebuggingServer() {
113 pref_port_.SetValue(0);
117 void RemoteDebuggingServer::OnPortChanged() {
118 int new_port = *pref_port_;
122 VLOG(1) << "OnPortChanged called: old_port=" << port_
123 << ", new_port=" << new_port;
125 if (new_port == port_) {
126 VLOG(1) << "Port has not been changed. Ignore silently.";
130 if (devtools_http_handler_) {
131 LOG(INFO) << "Stop old devtools: port=" << port_;
132 // Note: Stop destroys devtools_http_handler_.
133 devtools_http_handler_->Stop();
134 devtools_http_handler_ = NULL;
139 devtools_http_handler_ = content::DevToolsHttpHandler::Start(
140 CreateSocketFactory(port_),
142 new CastDevToolsDelegate(),
144 LOG(INFO) << "Devtools started: port=" << port_;
149 } // namespace chromecast