blob: 32b65bace89e5843f7730f939bfcf51c0fb8a7dc [file] [log] [blame]
[email protected]de7d61ff2013-08-20 11:30:411// Copyright 2013 The Chromium Authors. All rights reserved.
[email protected]ee75b8992012-01-27 07:53:572// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
vkuzkokovcbabd582014-11-06 13:53:545#include "content/shell/browser/shell_devtools_manager_delegate.h"
[email protected]ee75b8992012-01-27 07:53:576
avi66a07722015-12-25 23:38:127#include <stdint.h>
8
[email protected]90e6c5412013-04-16 22:45:259#include <vector>
10
pfeldmanf7c18d0242016-09-08 19:54:2611#include "base/atomicops.h"
[email protected]ed6635e2012-10-27 00:44:0912#include "base/bind.h"
[email protected]90e6c5412013-04-16 22:45:2513#include "base/command_line.h"
[email protected]0e60fce2014-06-04 22:27:2014#include "base/files/file_path.h"
avi66a07722015-12-25 23:38:1215#include "base/macros.h"
dcheng6003e0b2016-04-09 18:42:3416#include "base/memory/ptr_util.h"
[email protected]90e6c5412013-04-16 22:45:2517#include "base/strings/string_number_conversions.h"
[email protected]8dffd2c2013-12-02 14:14:3818#include "base/strings/stringprintf.h"
[email protected]852b34ba2013-10-03 16:29:0619#include "base/strings/utf_string_conversions.h"
avi66a07722015-12-25 23:38:1220#include "build/build_config.h"
yzshen6051dfd32015-10-20 19:23:2521#include "content/public/browser/browser_context.h"
[email protected]852b34ba2013-10-03 16:29:0622#include "content/public/browser/devtools_agent_host.h"
dgozman102fee92015-04-20 15:45:4623#include "content/public/browser/devtools_frontend_host.h"
pfeldmanf1a16942016-09-02 21:28:0024#include "content/public/browser/devtools_socket_factory.h"
[email protected]852b34ba2013-10-03 16:29:0625#include "content/public/browser/favicon_status.h"
26#include "content/public/browser/navigation_entry.h"
27#include "content/public/browser/render_view_host.h"
[email protected]eb040992012-10-10 16:56:0028#include "content/public/browser/web_contents.h"
[email protected]90e6c5412013-04-16 22:45:2529#include "content/public/common/content_switches.h"
[email protected]eb040992012-10-10 16:56:0030#include "content/public/common/url_constants.h"
[email protected]efd2c3f2014-03-11 09:57:2531#include "content/public/common/user_agent.h"
[email protected]de7d61ff2013-08-20 11:30:4132#include "content/shell/browser/shell.h"
dgozman102fee92015-04-20 15:45:4633#include "content/shell/common/shell_content_client.h"
[email protected]ee75b8992012-01-27 07:53:5734#include "grit/shell_resources.h"
vkuzkokov79426762015-01-13 08:03:0035#include "net/base/net_errors.h"
mikecironef22f9812016-10-04 03:40:1936#include "net/log/net_log_source.h"
byungchul38c3ae72014-08-25 23:27:4637#include "net/socket/tcp_server_socket.h"
[email protected]ee75b8992012-01-27 07:53:5738#include "ui/base/resource/resource_bundle.h"
39
[email protected]ed6635e2012-10-27 00:44:0940#if defined(OS_ANDROID)
41#include "content/public/browser/android/devtools_auth.h"
byungchul38c3ae72014-08-25 23:27:4642#include "net/socket/unix_domain_server_socket_posix.h"
[email protected]90e6c5412013-04-16 22:45:2543#endif
[email protected]ed6635e2012-10-27 00:44:0944
vkuzkokovcbabd582014-11-06 13:53:5445namespace content {
[email protected]852b34ba2013-10-03 16:29:0646
[email protected]ed6635e2012-10-27 00:44:0947namespace {
[email protected]90e6c5412013-04-16 22:45:2548
[email protected]8dffd2c2013-12-02 14:14:3849#if defined(OS_ANDROID)
50const char kFrontEndURL[] =
dgozmana1409c42014-11-19 16:06:1251 "http://chrome-devtools-frontend.appspot.com/serve_rev/%s/inspector.html";
[email protected]8dffd2c2013-12-02 14:14:3852#endif
[email protected]852b34ba2013-10-03 16:29:0653
vkuzkokov79426762015-01-13 08:03:0054const int kBackLog = 10;
55
pfeldmanf7c18d0242016-09-08 19:54:2656base::subtle::Atomic32 g_last_used_port;
57
byungchul38c3ae72014-08-25 23:27:4658#if defined(OS_ANDROID)
pfeldmanf1a16942016-09-02 21:28:0059class UnixDomainServerSocketFactory : public content::DevToolsSocketFactory {
byungchul38c3ae72014-08-25 23:27:4660 public:
61 explicit UnixDomainServerSocketFactory(const std::string& socket_name)
vkuzkokov79426762015-01-13 08:03:0062 : socket_name_(socket_name) {}
byungchul38c3ae72014-08-25 23:27:4663
64 private:
pfeldmanf1a16942016-09-02 21:28:0065 // content::DevToolsSocketFactory.
dcheng6003e0b2016-04-09 18:42:3466 std::unique_ptr<net::ServerSocket> CreateForHttpServer() override {
67 std::unique_ptr<net::UnixDomainServerSocket> socket(
tfarinaa7b245d2016-02-02 02:03:4968 new net::UnixDomainServerSocket(base::Bind(&CanUserConnectToDevTools),
69 true /* use_abstract_namespace */));
70 if (socket->BindAndListen(socket_name_, kBackLog) != net::OK)
dcheng6003e0b2016-04-09 18:42:3471 return std::unique_ptr<net::ServerSocket>();
vkuzkokov79426762015-01-13 08:03:0072
tfarinaa7b245d2016-02-02 02:03:4973 return std::move(socket);
byungchul38c3ae72014-08-25 23:27:4674 }
75
pfeldmanf1a16942016-09-02 21:28:0076 std::unique_ptr<net::ServerSocket> CreateForTethering(
77 std::string* out_name) override {
78 return nullptr;
79 }
80
vkuzkokov79426762015-01-13 08:03:0081 std::string socket_name_;
82
byungchul38c3ae72014-08-25 23:27:4683 DISALLOW_COPY_AND_ASSIGN(UnixDomainServerSocketFactory);
84};
85#else
pfeldmanf1a16942016-09-02 21:28:0086class TCPServerSocketFactory : public content::DevToolsSocketFactory {
byungchul38c3ae72014-08-25 23:27:4687 public:
avi66a07722015-12-25 23:38:1288 TCPServerSocketFactory(const std::string& address, uint16_t port)
89 : address_(address), port_(port) {}
byungchul38c3ae72014-08-25 23:27:4690
91 private:
pfeldmanf1a16942016-09-02 21:28:0092 // content::DevToolsSocketFactory.
dcheng6003e0b2016-04-09 18:42:3493 std::unique_ptr<net::ServerSocket> CreateForHttpServer() override {
94 std::unique_ptr<net::ServerSocket> socket(
mikecironef22f9812016-10-04 03:40:1995 new net::TCPServerSocket(nullptr, net::NetLogSource()));
vkuzkokov79426762015-01-13 08:03:0096 if (socket->ListenWithAddressAndPort(address_, port_, kBackLog) != net::OK)
dcheng6003e0b2016-04-09 18:42:3497 return std::unique_ptr<net::ServerSocket>();
vkuzkokov79426762015-01-13 08:03:0098
pfeldmanf7c18d0242016-09-08 19:54:2699 net::IPEndPoint endpoint;
100 if (socket->GetLocalAddress(&endpoint) == net::OK)
101 base::subtle::NoBarrier_Store(&g_last_used_port, endpoint.port());
102
vkuzkokov79426762015-01-13 08:03:00103 return socket;
byungchul38c3ae72014-08-25 23:27:46104 }
105
pfeldmanf1a16942016-09-02 21:28:00106 std::unique_ptr<net::ServerSocket> CreateForTethering(
107 std::string* out_name) override {
108 return nullptr;
109 }
110
vkuzkokov79426762015-01-13 08:03:00111 std::string address_;
avi66a07722015-12-25 23:38:12112 uint16_t port_;
vkuzkokov79426762015-01-13 08:03:00113
byungchul38c3ae72014-08-25 23:27:46114 DISALLOW_COPY_AND_ASSIGN(TCPServerSocketFactory);
115};
116#endif
117
pfeldmanf1a16942016-09-02 21:28:00118std::unique_ptr<content::DevToolsSocketFactory> CreateSocketFactory() {
avi83883c82014-12-23 00:08:49119 const base::CommandLine& command_line =
120 *base::CommandLine::ForCurrentProcess();
[email protected]90e6c5412013-04-16 22:45:25121#if defined(OS_ANDROID)
122 std::string socket_name = "content_shell_devtools_remote";
123 if (command_line.HasSwitch(switches::kRemoteDebuggingSocketName)) {
124 socket_name = command_line.GetSwitchValueASCII(
125 switches::kRemoteDebuggingSocketName);
126 }
pfeldmanf1a16942016-09-02 21:28:00127 return std::unique_ptr<content::DevToolsSocketFactory>(
byungchul38c3ae72014-08-25 23:27:46128 new UnixDomainServerSocketFactory(socket_name));
[email protected]90e6c5412013-04-16 22:45:25129#else
130 // See if the user specified a port on the command line (useful for
131 // automation). If not, use an ephemeral port by specifying 0.
avi66a07722015-12-25 23:38:12132 uint16_t port = 0;
[email protected]90e6c5412013-04-16 22:45:25133 if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) {
134 int temp_port;
135 std::string port_str =
136 command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
137 if (base::StringToInt(port_str, &temp_port) &&
yzshen6051dfd32015-10-20 19:23:25138 temp_port >= 0 && temp_port < 65535) {
avi66a07722015-12-25 23:38:12139 port = static_cast<uint16_t>(temp_port);
[email protected]90e6c5412013-04-16 22:45:25140 } else {
141 DLOG(WARNING) << "Invalid http debugger port number " << temp_port;
142 }
143 }
pfeldmanf1a16942016-09-02 21:28:00144 return std::unique_ptr<content::DevToolsSocketFactory>(
vkuzkokov79426762015-01-13 08:03:00145 new TCPServerSocketFactory("127.0.0.1", port));
[email protected]ed6635e2012-10-27 00:44:09146#endif
[email protected]90e6c5412013-04-16 22:45:25147}
[email protected]852b34ba2013-10-03 16:29:06148
pfeldman10628762016-09-08 07:59:26149} // namespace
vkuzkokovcbabd582014-11-06 13:53:54150
dgozman252e18d2014-09-22 12:40:06151// ShellDevToolsManagerDelegate ----------------------------------------------
152
vkuzkokovcbabd582014-11-06 13:53:54153// static
pfeldmanf7c18d0242016-09-08 19:54:26154int ShellDevToolsManagerDelegate::GetHttpHandlerPort() {
155 return base::subtle::NoBarrier_Load(&g_last_used_port);
156}
157
158// static
pfeldman10628762016-09-08 07:59:26159void ShellDevToolsManagerDelegate::StartHttpHandler(
vkuzkokovcbabd582014-11-06 13:53:54160 BrowserContext* browser_context) {
161 std::string frontend_url;
162#if defined(OS_ANDROID)
163 frontend_url = base::StringPrintf(kFrontEndURL, GetWebKitRevision().c_str());
164#endif
pfeldman10628762016-09-08 07:59:26165 DevToolsAgentHost::StartRemoteDebuggingServer(
dgozman102fee92015-04-20 15:45:46166 CreateSocketFactory(),
167 frontend_url,
yzshen6051dfd32015-10-20 19:23:25168 browser_context->GetPath(),
dgozman102fee92015-04-20 15:45:46169 base::FilePath(),
170 std::string(),
171 GetShellUserAgent());
vkuzkokovcbabd582014-11-06 13:53:54172}
173
pfeldman10628762016-09-08 07:59:26174// static
175void ShellDevToolsManagerDelegate::StopHttpHandler() {
176 DevToolsAgentHost::StopRemoteDebuggingServer();
177}
178
Pavel Feldman43f56b7c2016-08-30 00:04:35179ShellDevToolsManagerDelegate::ShellDevToolsManagerDelegate(
180 BrowserContext* browser_context)
181 : browser_context_(browser_context) {
dgozman252e18d2014-09-22 12:40:06182}
183
184ShellDevToolsManagerDelegate::~ShellDevToolsManagerDelegate() {
185}
186
Pavel Feldman43f56b7c2016-08-30 00:04:35187scoped_refptr<DevToolsAgentHost>
188ShellDevToolsManagerDelegate::CreateNewTarget(const GURL& url) {
189 Shell* shell = Shell::CreateNewWindow(browser_context_,
190 url,
191 nullptr,
192 gfx::Size());
193 return DevToolsAgentHost::GetOrCreateFor(shell->web_contents());
194}
195
pfeldman10628762016-09-08 07:59:26196std::string ShellDevToolsManagerDelegate::GetDiscoveryPageHTML() {
197#if defined(OS_ANDROID)
198 return std::string();
199#else
200 return ResourceBundle::GetSharedInstance().GetRawDataResource(
201 IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE).as_string();
202#endif
203}
204
205std::string ShellDevToolsManagerDelegate::GetFrontendResource(
206 const std::string& path) {
207 return content::DevToolsFrontendHost::GetFrontendResource(path).as_string();
208}
209
[email protected]ee75b8992012-01-27 07:53:57210} // namespace content