Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / chromecast / browser / devtools / remote_debugging_server.cc
blobdda2123e1ea7c7d0f8fec6a919fb81d2fce780bd
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"
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/string_number_conversions.h"
12 #include "base/strings/stringprintf.h"
13 #include "chromecast/browser/cast_browser_process.h"
14 #include "chromecast/browser/devtools/cast_dev_tools_delegate.h"
15 #include "chromecast/common/cast_content_client.h"
16 #include "chromecast/common/pref_names.h"
17 #include "components/devtools_http_handler/devtools_http_handler.h"
18 #include "content/public/browser/browser_context.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/common/content_switches.h"
21 #include "content/public/common/user_agent.h"
22 #include "net/base/net_errors.h"
23 #include "net/socket/tcp_server_socket.h"
25 #if defined(OS_ANDROID)
26 #include "content/public/browser/android/devtools_auth.h"
27 #include "net/socket/unix_domain_server_socket_posix.h"
28 #endif // defined(OS_ANDROID)
30 using devtools_http_handler::DevToolsHttpHandler;
32 namespace chromecast {
33 namespace shell {
35 namespace {
37 const char kFrontEndURL[] =
38 "https://chrome-devtools-frontend.appspot.com/serve_rev/%s/inspector.html";
39 const uint16 kDefaultRemoteDebuggingPort = 9222;
41 const int kBackLog = 10;
43 #if defined(OS_ANDROID)
44 class UnixDomainServerSocketFactory
45 : public DevToolsHttpHandler::ServerSocketFactory {
46 public:
47 explicit UnixDomainServerSocketFactory(const std::string& socket_name)
48 : socket_name_(socket_name) {}
50 private:
51 // devtools_http_handler::DevToolsHttpHandler::ServerSocketFactory.
52 scoped_ptr<net::ServerSocket> CreateForHttpServer() override {
53 scoped_ptr<net::ServerSocket> socket(
54 new net::UnixDomainServerSocket(
55 base::Bind(&content::CanUserConnectToDevTools),
56 true /* use_abstract_namespace */));
57 if (socket->ListenWithAddressAndPort(socket_name_, 0, kBackLog) != net::OK)
58 return scoped_ptr<net::ServerSocket>();
60 return socket;
63 std::string socket_name_;
65 DISALLOW_COPY_AND_ASSIGN(UnixDomainServerSocketFactory);
67 #else
68 class TCPServerSocketFactory
69 : public DevToolsHttpHandler::ServerSocketFactory {
70 public:
71 TCPServerSocketFactory(const std::string& address, uint16 port)
72 : address_(address), port_(port) {
75 private:
76 // devtools_http_handler::DevToolsHttpHandler::ServerSocketFactory.
77 scoped_ptr<net::ServerSocket> CreateForHttpServer() override {
78 scoped_ptr<net::ServerSocket> socket(
79 new net::TCPServerSocket(nullptr, net::NetLog::Source()));
80 if (socket->ListenWithAddressAndPort(address_, port_, kBackLog) != net::OK)
81 return scoped_ptr<net::ServerSocket>();
83 return socket;
86 std::string address_;
87 uint16 port_;
89 DISALLOW_COPY_AND_ASSIGN(TCPServerSocketFactory);
91 #endif
93 scoped_ptr<DevToolsHttpHandler::ServerSocketFactory>
94 CreateSocketFactory(uint16 port) {
95 #if defined(OS_ANDROID)
96 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
97 std::string socket_name = "cast_shell_devtools_remote";
98 if (command_line->HasSwitch(switches::kRemoteDebuggingSocketName)) {
99 socket_name = command_line->GetSwitchValueASCII(
100 switches::kRemoteDebuggingSocketName);
102 return scoped_ptr<DevToolsHttpHandler::ServerSocketFactory>(
103 new UnixDomainServerSocketFactory(socket_name));
104 #else
105 return scoped_ptr<DevToolsHttpHandler::ServerSocketFactory>(
106 new TCPServerSocketFactory("0.0.0.0", port));
107 #endif
110 std::string GetFrontendUrl() {
111 return base::StringPrintf(kFrontEndURL, content::GetWebKitRevision().c_str());
114 } // namespace
116 RemoteDebuggingServer::RemoteDebuggingServer()
117 : port_(kDefaultRemoteDebuggingPort) {
118 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
119 pref_enabled_.Init(prefs::kEnableRemoteDebugging,
120 CastBrowserProcess::GetInstance()->pref_service(),
121 base::Bind(&RemoteDebuggingServer::OnEnabledChanged,
122 base::Unretained(this)));
124 std::string port_str =
125 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
126 switches::kRemoteDebuggingPort);
127 if (!port_str.empty()) {
128 int port = kDefaultRemoteDebuggingPort;
129 if (base::StringToInt(port_str, &port)) {
130 port_ = static_cast<uint16>(port);
131 } else {
132 port_ = kDefaultRemoteDebuggingPort;
136 // Starts new dev tools, clearing port number saved in config.
137 // Remote debugging in production must be triggered only by config server.
138 pref_enabled_.SetValue(ShouldStartImmediately() && port_ != 0);
139 OnEnabledChanged();
142 RemoteDebuggingServer::~RemoteDebuggingServer() {
143 pref_enabled_.SetValue(false);
144 OnEnabledChanged();
147 void RemoteDebuggingServer::OnEnabledChanged() {
148 bool enabled = *pref_enabled_ && port_ != 0;
149 if (enabled && !devtools_http_handler_) {
150 devtools_http_handler_.reset(new DevToolsHttpHandler(
151 CreateSocketFactory(port_),
152 GetFrontendUrl(),
153 new CastDevToolsDelegate(),
154 base::FilePath(),
155 base::FilePath(),
156 std::string(),
157 GetUserAgent()));
158 LOG(INFO) << "Devtools started: port=" << port_;
159 } else if (!enabled && devtools_http_handler_) {
160 LOG(INFO) << "Stop devtools: port=" << port_;
161 devtools_http_handler_.reset();
165 } // namespace shell
166 } // namespace chromecast