blob: 957f36b239283f1a526ae2259748d473d767f760 [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
[email protected]ed6635e2012-10-27 00:44:0911#include "base/bind.h"
[email protected]90e6c5412013-04-16 22:45:2512#include "base/command_line.h"
[email protected]0e60fce2014-06-04 22:27:2013#include "base/files/file_path.h"
avi66a07722015-12-25 23:38:1214#include "base/macros.h"
dcheng6003e0b2016-04-09 18:42:3415#include "base/memory/ptr_util.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"
dgozman102fee92015-04-20 15:45:4620#include "components/devtools_http_handler/devtools_http_handler.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"
byungchul38c3ae72014-08-25 23:27:4636#include "net/socket/tcp_server_socket.h"
[email protected]ee75b8992012-01-27 07:53:5737#include "ui/base/resource/resource_bundle.h"
38
[email protected]ed6635e2012-10-27 00:44:0939#if defined(OS_ANDROID)
40#include "content/public/browser/android/devtools_auth.h"
byungchul38c3ae72014-08-25 23:27:4641#include "net/socket/unix_domain_server_socket_posix.h"
[email protected]90e6c5412013-04-16 22:45:2542#endif
[email protected]ed6635e2012-10-27 00:44:0943
dgozman102fee92015-04-20 15:45:4644using devtools_http_handler::DevToolsHttpHandler;
45
vkuzkokovcbabd582014-11-06 13:53:5446namespace content {
[email protected]852b34ba2013-10-03 16:29:0647
[email protected]ed6635e2012-10-27 00:44:0948namespace {
[email protected]90e6c5412013-04-16 22:45:2549
[email protected]8dffd2c2013-12-02 14:14:3850#if defined(OS_ANDROID)
51const char kFrontEndURL[] =
dgozmana1409c42014-11-19 16:06:1252 "http://chrome-devtools-frontend.appspot.com/serve_rev/%s/inspector.html";
[email protected]8dffd2c2013-12-02 14:14:3853#endif
[email protected]852b34ba2013-10-03 16:29:0654
vkuzkokov79426762015-01-13 08:03:0055const int kBackLog = 10;
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(
tfarinaa7b245d2016-02-02 02:03:4967 new net::UnixDomainServerSocket(base::Bind(&CanUserConnectToDevTools),
68 true /* use_abstract_namespace */));
69 if (socket->BindAndListen(socket_name_, kBackLog) != net::OK)
dcheng6003e0b2016-04-09 18:42:3470 return std::unique_ptr<net::ServerSocket>();
vkuzkokov79426762015-01-13 08:03:0071
tfarinaa7b245d2016-02-02 02:03:4972 return std::move(socket);
byungchul38c3ae72014-08-25 23:27:4673 }
74
pfeldmanf1a16942016-09-02 21:28:0075 std::unique_ptr<net::ServerSocket> CreateForTethering(
76 std::string* out_name) override {
77 return nullptr;
78 }
79
vkuzkokov79426762015-01-13 08:03:0080 std::string socket_name_;
81
byungchul38c3ae72014-08-25 23:27:4682 DISALLOW_COPY_AND_ASSIGN(UnixDomainServerSocketFactory);
83};
84#else
pfeldmanf1a16942016-09-02 21:28:0085class TCPServerSocketFactory : public content::DevToolsSocketFactory {
byungchul38c3ae72014-08-25 23:27:4686 public:
avi66a07722015-12-25 23:38:1287 TCPServerSocketFactory(const std::string& address, uint16_t port)
88 : address_(address), port_(port) {}
byungchul38c3ae72014-08-25 23:27:4689
90 private:
pfeldmanf1a16942016-09-02 21:28:0091 // content::DevToolsSocketFactory.
dcheng6003e0b2016-04-09 18:42:3492 std::unique_ptr<net::ServerSocket> CreateForHttpServer() override {
93 std::unique_ptr<net::ServerSocket> socket(
vkuzkokov79426762015-01-13 08:03:0094 new net::TCPServerSocket(nullptr, net::NetLog::Source()));
95 if (socket->ListenWithAddressAndPort(address_, port_, kBackLog) != net::OK)
dcheng6003e0b2016-04-09 18:42:3496 return std::unique_ptr<net::ServerSocket>();
vkuzkokov79426762015-01-13 08:03:0097
98 return socket;
byungchul38c3ae72014-08-25 23:27:4699 }
100
pfeldmanf1a16942016-09-02 21:28:00101 std::unique_ptr<net::ServerSocket> CreateForTethering(
102 std::string* out_name) override {
103 return nullptr;
104 }
105
vkuzkokov79426762015-01-13 08:03:00106 std::string address_;
avi66a07722015-12-25 23:38:12107 uint16_t port_;
vkuzkokov79426762015-01-13 08:03:00108
byungchul38c3ae72014-08-25 23:27:46109 DISALLOW_COPY_AND_ASSIGN(TCPServerSocketFactory);
110};
111#endif
112
pfeldmanf1a16942016-09-02 21:28:00113std::unique_ptr<content::DevToolsSocketFactory> CreateSocketFactory() {
avi83883c82014-12-23 00:08:49114 const base::CommandLine& command_line =
115 *base::CommandLine::ForCurrentProcess();
[email protected]90e6c5412013-04-16 22:45:25116#if defined(OS_ANDROID)
117 std::string socket_name = "content_shell_devtools_remote";
118 if (command_line.HasSwitch(switches::kRemoteDebuggingSocketName)) {
119 socket_name = command_line.GetSwitchValueASCII(
120 switches::kRemoteDebuggingSocketName);
121 }
pfeldmanf1a16942016-09-02 21:28:00122 return std::unique_ptr<content::DevToolsSocketFactory>(
byungchul38c3ae72014-08-25 23:27:46123 new UnixDomainServerSocketFactory(socket_name));
[email protected]90e6c5412013-04-16 22:45:25124#else
125 // See if the user specified a port on the command line (useful for
126 // automation). If not, use an ephemeral port by specifying 0.
avi66a07722015-12-25 23:38:12127 uint16_t port = 0;
[email protected]90e6c5412013-04-16 22:45:25128 if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) {
129 int temp_port;
130 std::string port_str =
131 command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
132 if (base::StringToInt(port_str, &temp_port) &&
yzshen6051dfd32015-10-20 19:23:25133 temp_port >= 0 && temp_port < 65535) {
avi66a07722015-12-25 23:38:12134 port = static_cast<uint16_t>(temp_port);
[email protected]90e6c5412013-04-16 22:45:25135 } else {
136 DLOG(WARNING) << "Invalid http debugger port number " << temp_port;
137 }
138 }
pfeldmanf1a16942016-09-02 21:28:00139 return std::unique_ptr<content::DevToolsSocketFactory>(
vkuzkokov79426762015-01-13 08:03:00140 new TCPServerSocketFactory("127.0.0.1", port));
[email protected]ed6635e2012-10-27 00:44:09141#endif
[email protected]90e6c5412013-04-16 22:45:25142}
[email protected]852b34ba2013-10-03 16:29:06143
dgozman252e18d2014-09-22 12:40:06144// ShellDevToolsDelegate ----------------------------------------------------
145
dgozman102fee92015-04-20 15:45:46146class ShellDevToolsDelegate :
147 public devtools_http_handler::DevToolsHttpHandlerDelegate {
vkuzkokovcbabd582014-11-06 13:53:54148 public:
Pavel Feldman43f56b7c2016-08-30 00:04:35149 explicit ShellDevToolsDelegate();
vkuzkokovcbabd582014-11-06 13:53:54150 ~ShellDevToolsDelegate() override;
151
dgozman102fee92015-04-20 15:45:46152 // devtools_http_handler::DevToolsHttpHandlerDelegate implementation.
vkuzkokovcbabd582014-11-06 13:53:54153 std::string GetDiscoveryPageHTML() override;
dgozman102fee92015-04-20 15:45:46154 std::string GetFrontendResource(const std::string& path) override;
vkuzkokovcbabd582014-11-06 13:53:54155
156 private:
vkuzkokovcbabd582014-11-06 13:53:54157 DISALLOW_COPY_AND_ASSIGN(ShellDevToolsDelegate);
158};
159
Pavel Feldman43f56b7c2016-08-30 00:04:35160ShellDevToolsDelegate::ShellDevToolsDelegate() {
[email protected]ee75b8992012-01-27 07:53:57161}
162
163ShellDevToolsDelegate::~ShellDevToolsDelegate() {
164}
165
[email protected]ee75b8992012-01-27 07:53:57166std::string ShellDevToolsDelegate::GetDiscoveryPageHTML() {
[email protected]8dffd2c2013-12-02 14:14:38167#if defined(OS_ANDROID)
168 return std::string();
169#else
[email protected]ee75b8992012-01-27 07:53:57170 return ResourceBundle::GetSharedInstance().GetRawDataResource(
[email protected]4d8bb1a92012-11-01 21:12:40171 IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE).as_string();
[email protected]8dffd2c2013-12-02 14:14:38172#endif
[email protected]ee75b8992012-01-27 07:53:57173}
174
dgozman102fee92015-04-20 15:45:46175std::string ShellDevToolsDelegate::GetFrontendResource(
176 const std::string& path) {
177 return content::DevToolsFrontendHost::GetFrontendResource(path).as_string();
[email protected]ee75b8992012-01-27 07:53:57178}
179
vkuzkokovcbabd582014-11-06 13:53:54180} // namespace
181
dgozman252e18d2014-09-22 12:40:06182// ShellDevToolsManagerDelegate ----------------------------------------------
183
vkuzkokovcbabd582014-11-06 13:53:54184// static
185DevToolsHttpHandler*
186ShellDevToolsManagerDelegate::CreateHttpHandler(
187 BrowserContext* browser_context) {
188 std::string frontend_url;
189#if defined(OS_ANDROID)
190 frontend_url = base::StringPrintf(kFrontEndURL, GetWebKitRevision().c_str());
191#endif
dgozman102fee92015-04-20 15:45:46192 return new DevToolsHttpHandler(
193 CreateSocketFactory(),
194 frontend_url,
Pavel Feldman43f56b7c2016-08-30 00:04:35195 new ShellDevToolsDelegate(),
yzshen6051dfd32015-10-20 19:23:25196 browser_context->GetPath(),
dgozman102fee92015-04-20 15:45:46197 base::FilePath(),
198 std::string(),
199 GetShellUserAgent());
vkuzkokovcbabd582014-11-06 13:53:54200}
201
Pavel Feldman43f56b7c2016-08-30 00:04:35202ShellDevToolsManagerDelegate::ShellDevToolsManagerDelegate(
203 BrowserContext* browser_context)
204 : browser_context_(browser_context) {
dgozman252e18d2014-09-22 12:40:06205}
206
207ShellDevToolsManagerDelegate::~ShellDevToolsManagerDelegate() {
208}
209
210base::DictionaryValue* ShellDevToolsManagerDelegate::HandleCommand(
211 DevToolsAgentHost* agent_host,
alexclarke72564fc2016-07-07 08:07:57212 base::DictionaryValue* command_dict) {
Pavel Feldman43f56b7c2016-08-30 00:04:35213 return nullptr;
dgozman252e18d2014-09-22 12:40:06214}
215
pfeldmana9e7dda2016-08-26 14:35:17216std::string ShellDevToolsManagerDelegate::GetTargetType(RenderFrameHost* host) {
217 return DevToolsAgentHost::kTypePage;
218}
219
220std::string ShellDevToolsManagerDelegate::GetTargetTitle(
221 RenderFrameHost* host) {
222 return "";
223}
224
Pavel Feldman43f56b7c2016-08-30 00:04:35225
226scoped_refptr<DevToolsAgentHost>
227ShellDevToolsManagerDelegate::CreateNewTarget(const GURL& url) {
228 Shell* shell = Shell::CreateNewWindow(browser_context_,
229 url,
230 nullptr,
231 gfx::Size());
232 return DevToolsAgentHost::GetOrCreateFor(shell->web_contents());
233}
234
[email protected]ee75b8992012-01-27 07:53:57235} // namespace content