Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / chromecast / browser / devtools / remote_debugging_server.cc
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.
4
5 #include "chromecast/browser/devtools/remote_debugging_server.h"
6
7 #include "base/bind.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"
21
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)
26
27 namespace chromecast {
28 namespace shell {
29
30 namespace {
31
32 const char kFrontEndURL[] =
33     "https://chrome-devtools-frontend.appspot.com/serve_rev/%s/devtools.html";
34 const int kDefaultRemoteDebuggingPort = 9222;
35
36 #if defined(OS_ANDROID)
37 class UnixDomainServerSocketFactory
38     : public content::DevToolsHttpHandler::ServerSocketFactory {
39  public:
40   explicit UnixDomainServerSocketFactory(const std::string& socket_name)
41       : content::DevToolsHttpHandler::ServerSocketFactory(socket_name, 0, 1) {}
42
43  private:
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 */));
50   }
51
52   DISALLOW_COPY_AND_ASSIGN(UnixDomainServerSocketFactory);
53 };
54 #else
55 class TCPServerSocketFactory
56     : public content::DevToolsHttpHandler::ServerSocketFactory {
57  public:
58   TCPServerSocketFactory(const std::string& address, int port, int backlog)
59       : content::DevToolsHttpHandler::ServerSocketFactory(
60             address, port, backlog) {}
61
62  private:
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()));
67   }
68
69   DISALLOW_COPY_AND_ASSIGN(TCPServerSocketFactory);
70 };
71 #endif
72
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);
81   }
82   return scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory>(
83       new UnixDomainServerSocketFactory(socket_name));
84 #else
85   return scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory>(
86       new TCPServerSocketFactory("0.0.0.0", port, 1));
87 #endif
88 }
89
90 std::string GetFrontendUrl() {
91   return base::StringPrintf(kFrontEndURL, content::GetWebKitRevision().c_str());
92 }
93
94 }  // namespace
95
96 RemoteDebuggingServer::RemoteDebuggingServer()
97     : devtools_http_handler_(NULL),
98       port_(0) {
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)));
104
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);
109   OnPortChanged();
110 }
111
112 RemoteDebuggingServer::~RemoteDebuggingServer() {
113   pref_port_.SetValue(0);
114   OnPortChanged();
115 }
116
117 void RemoteDebuggingServer::OnPortChanged() {
118   int new_port = *pref_port_;
119   if (new_port < 0) {
120     new_port = 0;
121   }
122   VLOG(1) << "OnPortChanged called: old_port=" << port_
123           << ", new_port=" << new_port;
124
125   if (new_port == port_) {
126     VLOG(1) << "Port has not been changed. Ignore silently.";
127     return;
128   }
129
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;
135   }
136
137   port_ = new_port;
138   if (port_ > 0) {
139     devtools_http_handler_ = content::DevToolsHttpHandler::Start(
140         CreateSocketFactory(port_),
141         GetFrontendUrl(),
142         new CastDevToolsDelegate(),
143         base::FilePath());
144     LOG(INFO) << "Devtools started: port=" << port_;
145   }
146 }
147
148 }  // namespace shell
149 }  // namespace chromecast