blob: a3b04f8845856e8a56a4bf5bb4414d967db7637c [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"
[email protected]90e6c5412013-04-16 22:45:2516#include "base/strings/string_number_conversions.h"
[email protected]8dffd2c2013-12-02 14:14:3817#include "base/strings/stringprintf.h"
[email protected]852b34ba2013-10-03 16:29:0618#include "base/strings/utf_string_conversions.h"
avi66a07722015-12-25 23:38:1219#include "build/build_config.h"
yzshen6051dfd32015-10-20 19:23:2520#include "content/public/browser/browser_context.h"
[email protected]852b34ba2013-10-03 16:29:0621#include "content/public/browser/devtools_agent_host.h"
pfeldmanf1a16942016-09-02 21:28:0022#include "content/public/browser/devtools_socket_factory.h"
[email protected]852b34ba2013-10-03 16:29:0623#include "content/public/browser/favicon_status.h"
24#include "content/public/browser/navigation_entry.h"
25#include "content/public/browser/render_view_host.h"
[email protected]eb040992012-10-10 16:56:0026#include "content/public/browser/web_contents.h"
[email protected]90e6c5412013-04-16 22:45:2527#include "content/public/common/content_switches.h"
[email protected]eb040992012-10-10 16:56:0028#include "content/public/common/url_constants.h"
[email protected]efd2c3f2014-03-11 09:57:2529#include "content/public/common/user_agent.h"
[email protected]de7d61ff2013-08-20 11:30:4130#include "content/shell/browser/shell.h"
Kent Tamuraf92649d882018-12-03 09:07:4731#include "content/shell/browser/web_test/secondary_test_window_observer.h"
dgozman102fee92015-04-20 15:45:4632#include "content/shell/common/shell_content_client.h"
dgozman4547460932017-06-22 03:04:3633#include "content/shell/common/shell_switches.h"
thakisda47dac2017-02-27 14:35:3034#include "content/shell/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
chenwilliame88d8362017-03-21 02:34:3040#if !defined(OS_ANDROID)
41#include "content/public/browser/devtools_frontend_host.h"
42#endif
43
[email protected]ed6635e2012-10-27 00:44:0944#if defined(OS_ANDROID)
45#include "content/public/browser/android/devtools_auth.h"
byungchul38c3ae72014-08-25 23:27:4646#include "net/socket/unix_domain_server_socket_posix.h"
[email protected]90e6c5412013-04-16 22:45:2547#endif
[email protected]ed6635e2012-10-27 00:44:0948
vkuzkokovcbabd582014-11-06 13:53:5449namespace content {
[email protected]852b34ba2013-10-03 16:29:0650
[email protected]ed6635e2012-10-27 00:44:0951namespace {
[email protected]90e6c5412013-04-16 22:45:2552
vkuzkokov79426762015-01-13 08:03:0053const int kBackLog = 10;
54
pfeldmanf7c18d0242016-09-08 19:54:2655base::subtle::Atomic32 g_last_used_port;
56
byungchul38c3ae72014-08-25 23:27:4657#if defined(OS_ANDROID)
pfeldmanf1a16942016-09-02 21:28:0058class UnixDomainServerSocketFactory : public content::DevToolsSocketFactory {
byungchul38c3ae72014-08-25 23:27:4659 public:
60 explicit UnixDomainServerSocketFactory(const std::string& socket_name)
vkuzkokov79426762015-01-13 08:03:0061 : socket_name_(socket_name) {}
byungchul38c3ae72014-08-25 23:27:4662
63 private:
pfeldmanf1a16942016-09-02 21:28:0064 // content::DevToolsSocketFactory.
dcheng6003e0b2016-04-09 18:42:3465 std::unique_ptr<net::ServerSocket> CreateForHttpServer() override {
66 std::unique_ptr<net::UnixDomainServerSocket> socket(
danakjc988f0be2019-05-17 20:48:0167 new net::UnixDomainServerSocket(
68 base::BindRepeating(&CanUserConnectToDevTools),
69 true /* use_abstract_namespace */));
tfarinaa7b245d2016-02-02 02:03:4970 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;
pfeldman10628762016-09-08 07:59:26162 DevToolsAgentHost::StartRemoteDebuggingServer(
Pavel Feldmanc8a484b52018-02-07 21:07:32163 CreateSocketFactory(), browser_context->GetPath(), base::FilePath());
Pavel Feldman2b11e2352017-10-25 05:24:01164
165 const base::CommandLine& command_line =
166 *base::CommandLine::ForCurrentProcess();
167 if (command_line.HasSwitch(switches::kRemoteDebuggingPipe))
168 DevToolsAgentHost::StartRemoteDebuggingPipeHandler();
vkuzkokovcbabd582014-11-06 13:53:54169}
170
pfeldman10628762016-09-08 07:59:26171// static
172void ShellDevToolsManagerDelegate::StopHttpHandler() {
173 DevToolsAgentHost::StopRemoteDebuggingServer();
174}
175
Pavel Feldman43f56b7c2016-08-30 00:04:35176ShellDevToolsManagerDelegate::ShellDevToolsManagerDelegate(
177 BrowserContext* browser_context)
178 : browser_context_(browser_context) {
dgozman252e18d2014-09-22 12:40:06179}
180
181ShellDevToolsManagerDelegate::~ShellDevToolsManagerDelegate() {
182}
183
Andrey Lushnikov36299bc2018-08-23 22:09:54184BrowserContext* ShellDevToolsManagerDelegate::GetDefaultBrowserContext() {
185 return browser_context_;
186}
187
Andrey Lushnikovdf1651982018-09-14 19:00:37188void ShellDevToolsManagerDelegate::ClientAttached(
189 content::DevToolsAgentHost* agent_host,
190 content::DevToolsAgentHostClient* client) {
191 // Make sure we don't receive notifications twice for the same client.
192 CHECK(clients_.find(client) == clients_.end());
193 clients_.insert(client);
194}
195
196void ShellDevToolsManagerDelegate::ClientDetached(
197 content::DevToolsAgentHost* agent_host,
198 content::DevToolsAgentHostClient* client) {
199 clients_.erase(client);
200}
201
Pavel Feldman43f56b7c2016-08-30 00:04:35202scoped_refptr<DevToolsAgentHost>
203ShellDevToolsManagerDelegate::CreateNewTarget(const GURL& url) {
204 Shell* shell = Shell::CreateNewWindow(browser_context_,
205 url,
206 nullptr,
207 gfx::Size());
Kent Tamuracd3ebc42018-05-16 06:44:22208 if (switches::IsRunWebTestsSwitchPresent())
dgozman4547460932017-06-22 03:04:36209 SecondaryTestWindowObserver::CreateForWebContents(shell->web_contents());
Pavel Feldman43f56b7c2016-08-30 00:04:35210 return DevToolsAgentHost::GetOrCreateFor(shell->web_contents());
211}
212
pfeldman10628762016-09-08 07:59:26213std::string ShellDevToolsManagerDelegate::GetDiscoveryPageHTML() {
214#if defined(OS_ANDROID)
215 return std::string();
216#else
Lei Zhangcf30efc2017-10-04 21:31:24217 return ui::ResourceBundle::GetSharedInstance()
218 .GetRawDataResource(IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE)
219 .as_string();
pfeldman10628762016-09-08 07:59:26220#endif
221}
222
Pavel Feldmanc8a484b52018-02-07 21:07:32223bool ShellDevToolsManagerDelegate::HasBundledFrontendResources() {
chenwilliame88d8362017-03-21 02:34:30224#if defined(OS_ANDROID)
Pavel Feldmanc8a484b52018-02-07 21:07:32225 return false;
chenwilliame88d8362017-03-21 02:34:30226#endif
Pavel Feldmanc8a484b52018-02-07 21:07:32227 return true;
pfeldman10628762016-09-08 07:59:26228}
229
[email protected]ee75b8992012-01-27 07:53:57230} // namespace content