summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/devtools
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-08 14:30:41 +0200
committerJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-12 13:49:54 +0200
commitab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch)
tree498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/content/browser/devtools
parent4ce69f7403811819800e7c5ae1318b2647e778d1 (diff)
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/content/browser/devtools')
-rw-r--r--chromium/content/browser/devtools/BUILD.gn71
-rw-r--r--chromium/content/browser/devtools/browser_protocol.json3
-rw-r--r--chromium/content/browser/devtools/devtools_agent_host_impl.cc12
-rw-r--r--chromium/content/browser/devtools/devtools_agent_host_impl.h2
-rw-r--r--chromium/content/browser/devtools/devtools_browser_target.cc53
-rw-r--r--chromium/content/browser/devtools/devtools_browser_target.h8
-rw-r--r--chromium/content/browser/devtools/devtools_external_agent_proxy_impl.cc73
-rw-r--r--chromium/content/browser/devtools/devtools_external_agent_proxy_impl.h35
-rw-r--r--chromium/content/browser/devtools/devtools_http_handler_impl.cc112
-rw-r--r--chromium/content/browser/devtools/devtools_http_handler_impl.h11
-rw-r--r--chromium/content/browser/devtools/devtools_http_handler_unittest.cc50
-rw-r--r--chromium/content/browser/devtools/devtools_manager_impl.cc13
-rw-r--r--chromium/content/browser/devtools/devtools_manager_impl.h9
-rw-r--r--chromium/content/browser/devtools/devtools_manager_unittest.cc10
-rw-r--r--chromium/content/browser/devtools/devtools_netlog_observer.cc134
-rw-r--r--chromium/content/browser/devtools/devtools_netlog_observer.h13
-rw-r--r--chromium/content/browser/devtools/devtools_power_handler.cc83
-rw-r--r--chromium/content/browser/devtools/devtools_power_handler.h38
-rw-r--r--chromium/content/browser/devtools/devtools_protocol.cc43
-rw-r--r--chromium/content/browser/devtools/devtools_protocol.h18
-rw-r--r--chromium/content/browser/devtools/devtools_protocol_constants.cc293
-rw-r--r--chromium/content/browser/devtools/devtools_protocol_constants.h296
-rw-r--r--chromium/content/browser/devtools/devtools_resources.gyp40
-rw-r--r--chromium/content/browser/devtools/devtools_system_info_handler.cc7
-rw-r--r--chromium/content/browser/devtools/devtools_tracing_handler.cc103
-rw-r--r--chromium/content/browser/devtools/devtools_tracing_handler.h23
-rw-r--r--chromium/content/browser/devtools/embedded_worker_devtools_manager.cc379
-rw-r--r--chromium/content/browser/devtools/embedded_worker_devtools_manager.h138
-rw-r--r--chromium/content/browser/devtools/embedded_worker_devtools_manager_unittest.cc272
-rw-r--r--chromium/content/browser/devtools/forwarding_agent_host.cc41
-rw-r--r--chromium/content/browser/devtools/forwarding_agent_host.h39
-rw-r--r--chromium/content/browser/devtools/ipc_devtools_agent_host.cc7
-rw-r--r--chromium/content/browser/devtools/render_view_devtools_agent_host.cc138
-rw-r--r--chromium/content/browser/devtools/render_view_devtools_agent_host.h16
-rw-r--r--chromium/content/browser/devtools/renderer_overrides_handler.cc168
-rw-r--r--chromium/content/browser/devtools/renderer_overrides_handler.h12
-rw-r--r--chromium/content/browser/devtools/renderer_overrides_handler_browsertest.cc11
-rw-r--r--chromium/content/browser/devtools/tethering_handler.cc2
-rw-r--r--chromium/content/browser/devtools/worker_devtools_manager.cc38
-rw-r--r--chromium/content/browser/devtools/worker_devtools_manager.h12
-rw-r--r--chromium/content/browser/devtools/worker_devtools_message_filter.cc11
-rw-r--r--chromium/content/browser/devtools/worker_devtools_message_filter.h3
42 files changed, 1761 insertions, 1079 deletions
diff --git a/chromium/content/browser/devtools/BUILD.gn b/chromium/content/browser/devtools/BUILD.gn
new file mode 100644
index 00000000000..4aab2bab11e
--- /dev/null
+++ b/chromium/content/browser/devtools/BUILD.gn
@@ -0,0 +1,71 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//tools/grit/grit_rule.gni")
+
+# In GYP: devtools_resources target.
+group("resources") {
+ deps = [
+ ":devtools_resources",
+ ":devtools_protocol_constants",
+ ]
+}
+
+# In GYP: devtools_resources action in the devtools_resources target.
+action("devtools_resources") {
+ visibility = ":resources"
+
+ # This can't use grit_rule.gni because the grd file is generated at build
+ # time, so the trick of using grit_info to get the real inputs/outputs at GYP
+ # time isn't possible.
+ script = "//tools/grit/grit.py"
+
+ grdfile = "$root_gen_dir/devtools/devtools_resources.grd"
+
+ source_prereqs = [ grdfile ] +
+ rebase_path(exec_script("//tools/grit/grit_info.py", [ "--inputs" ],
+ "list lines"),
+ ".", "//")
+
+ out_dir = "$root_gen_dir/webkit"
+ outputs = [
+ "$out_dir/grit/devtools_resources.h",
+ "$out_dir/devtools_resources.pak",
+ "$out_dir/grit/devtools_resources_map.cc",
+ "$out_dir/grit/devtools_resources_map.h",
+ ]
+
+ args = [
+ "-i", rebase_path(grdfile, root_build_dir), "build",
+ "-f", rebase_path("//tools/gritsettings/resource_ids", root_build_dir),
+ "-o", rebase_path(out_dir, root_build_dir),
+ "-D", "SHARED_INTERMEDIATE_DIR=" +
+ rebase_path(root_gen_dir, root_build_dir),
+ ] + grit_defines
+
+ deps = [
+ # This is the action that generates out .grd input file.
+ "//third_party/WebKit/public:blink_generate_devtools_grd",
+ ]
+}
+
+action("devtools_protocol_constants") {
+ visibility = ":resources"
+
+ script = "//content/public/browser/devtools_protocol_constants_generator.py"
+
+ blink_protocol = "//third_party/WebKit/Source/devtools/protocol.json"
+ browser_protocol = "browser_protocol.json"
+ source_prereqs = [ blink_protocol, browser_protocol ]
+
+ outputs = [
+ "$target_gen_dir/devtools_protocol_constants.cc",
+ "$target_gen_dir/devtools_protocol_constants.h",
+ ]
+
+ args = [ "content" ] + rebase_path(outputs, root_build_dir) + [
+ rebase_path(blink_protocol, root_build_dir),
+ rebase_path(browser_protocol, root_build_dir),
+ ]
+}
diff --git a/chromium/content/browser/devtools/browser_protocol.json b/chromium/content/browser/devtools/browser_protocol.json
index 59e73c0c590..dfb462febf2 100644
--- a/chromium/content/browser/devtools/browser_protocol.json
+++ b/chromium/content/browser/devtools/browser_protocol.json
@@ -22,7 +22,8 @@
"properties": [
{ "name": "devices", "type": "array", "items": { "$ref": "GPUDevice" }, "description": "The graphics devices on the system. Element 0 is the primary GPU." },
{ "name": "auxAttributes", "type": "object", "optional": "true", "description": "An optional dictionary of additional GPU related attributes." },
- { "name": "featureStatus", "type": "object", "optional": "true", "description": "An optional dictionary of graphics features and their status." }
+ { "name": "featureStatus", "type": "object", "optional": "true", "description": "An optional dictionary of graphics features and their status." },
+ { "name": "driverBugWorkarounds", "type": "array", "items": { "type": "string" }, "description": "An optional array of GPU driver bug workarounds." }
],
"description": "Provides information about the GPU(s) on the system."
},
diff --git a/chromium/content/browser/devtools/devtools_agent_host_impl.cc b/chromium/content/browser/devtools/devtools_agent_host_impl.cc
index 087004296d5..bcb60b55b78 100644
--- a/chromium/content/browser/devtools/devtools_agent_host_impl.cc
+++ b/chromium/content/browser/devtools/devtools_agent_host_impl.cc
@@ -10,6 +10,7 @@
#include "base/guid.h"
#include "base/lazy_instance.h"
#include "content/browser/devtools/devtools_manager_impl.h"
+#include "content/browser/devtools/forwarding_agent_host.h"
#include "content/public/browser/browser_thread.h"
namespace content {
@@ -31,6 +32,7 @@ DevToolsAgentHostImpl::~DevToolsAgentHostImpl() {
g_instances.Get().erase(g_instances.Get().find(id_));
}
+//static
scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::GetForId(
const std::string& id) {
if (g_instances == NULL)
@@ -41,6 +43,12 @@ scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::GetForId(
return it->second;
}
+//static
+scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::Create(
+ DevToolsExternalAgentProxyDelegate* delegate) {
+ return new ForwardingAgentHost(delegate);
+}
+
bool DevToolsAgentHostImpl::IsAttached() {
return !!DevToolsManagerImpl::GetInstance()->GetDevToolsClientHostFor(this);
}
@@ -60,6 +68,10 @@ void DevToolsAgentHostImpl::DisconnectRenderViewHost() {}
void DevToolsAgentHostImpl::ConnectRenderViewHost(RenderViewHost* rvh) {}
+bool DevToolsAgentHostImpl::IsWorker() const {
+ return false;
+}
+
void DevToolsAgentHostImpl::NotifyCloseListener() {
if (close_listener_) {
scoped_refptr<DevToolsAgentHostImpl> protect(this);
diff --git a/chromium/content/browser/devtools/devtools_agent_host_impl.h b/chromium/content/browser/devtools/devtools_agent_host_impl.h
index 9bd800dc398..d0fad668b49 100644
--- a/chromium/content/browser/devtools/devtools_agent_host_impl.h
+++ b/chromium/content/browser/devtools/devtools_agent_host_impl.h
@@ -53,6 +53,8 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
virtual void ConnectRenderViewHost(RenderViewHost* rvh) OVERRIDE;
+ virtual bool IsWorker() const OVERRIDE;
+
protected:
DevToolsAgentHostImpl();
virtual ~DevToolsAgentHostImpl();
diff --git a/chromium/content/browser/devtools/devtools_browser_target.cc b/chromium/content/browser/devtools/devtools_browser_target.cc
index a782462ba4c..b050152d2e4 100644
--- a/chromium/content/browser/devtools/devtools_browser_target.cc
+++ b/chromium/content/browser/devtools/devtools_browser_target.cc
@@ -5,9 +5,12 @@
#include "content/browser/devtools/devtools_browser_target.h"
#include "base/bind.h"
+#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/message_loop/message_loop_proxy.h"
+#include "base/stl_util.h"
+#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "content/public/browser/browser_thread.h"
#include "net/server/http_server.h"
@@ -15,13 +18,11 @@
namespace content {
DevToolsBrowserTarget::DevToolsBrowserTarget(
- base::MessageLoopProxy* message_loop_proxy,
net::HttpServer* http_server,
int connection_id)
- : message_loop_proxy_(message_loop_proxy),
+ : message_loop_proxy_(base::MessageLoopProxy::current()),
http_server_(http_server),
connection_id_(connection_id),
- handlers_deleter_(&handlers_),
weak_factory_(this) {
}
@@ -29,6 +30,8 @@ void DevToolsBrowserTarget::RegisterDomainHandler(
const std::string& domain,
DevToolsProtocol::Handler* handler,
bool handle_on_ui_thread) {
+ DCHECK_EQ(message_loop_proxy_, base::MessageLoopProxy::current());
+
DCHECK(handlers_.find(domain) == handlers_.end());
handlers_[domain] = handler;
if (handle_on_ui_thread) {
@@ -41,7 +44,11 @@ void DevToolsBrowserTarget::RegisterDomainHandler(
}
}
+typedef std::map<std::string, DevToolsBrowserTarget*> DomainMap;
+base::LazyInstance<DomainMap>::Leaky g_used_domains = LAZY_INSTANCE_INITIALIZER;
+
void DevToolsBrowserTarget::HandleMessage(const std::string& data) {
+ DCHECK_EQ(message_loop_proxy_, base::MessageLoopProxy::current());
std::string error_response;
scoped_refptr<DevToolsProtocol::Command> command =
DevToolsProtocol::ParseCommand(data, &error_response);
@@ -55,9 +62,21 @@ void DevToolsBrowserTarget::HandleMessage(const std::string& data) {
Respond(command->NoSuchMethodErrorResponse()->Serialize());
return;
}
+ DomainMap& used_domains(g_used_domains.Get());
+ std::string domain = command->domain();
+ DomainMap::iterator jt = used_domains.find(domain);
+ if (jt == used_domains.end()) {
+ used_domains[domain] = this;
+ } else if (jt->second != this) {
+ std::string message =
+ base::StringPrintf("'%s' is held by another connection",
+ domain.c_str());
+ Respond(command->ServerErrorResponse(message)->Serialize());
+ return;
+ }
DevToolsProtocol::Handler* handler = it->second;
- bool handle_directly = handle_on_ui_thread_.find(command->domain()) ==
+ bool handle_directly = handle_on_ui_thread_.find(domain) ==
handle_on_ui_thread_.end();
if (handle_directly) {
scoped_refptr<DevToolsProtocol::Response> response =
@@ -81,9 +100,23 @@ void DevToolsBrowserTarget::HandleMessage(const std::string& data) {
}
void DevToolsBrowserTarget::Detach() {
- message_loop_proxy_ = NULL;
+ DCHECK_EQ(message_loop_proxy_, base::MessageLoopProxy::current());
+ DCHECK(http_server_);
+
http_server_ = NULL;
+ DomainMap& used_domains(g_used_domains.Get());
+ for (DomainMap::iterator it = used_domains.begin();
+ it != used_domains.end();) {
+ if (it->second == this) {
+ DomainMap::iterator to_erase = it;
+ ++it;
+ used_domains.erase(to_erase);
+ } else {
+ ++it;
+ }
+ }
+
std::vector<DevToolsProtocol::Handler*> ui_handlers;
for (std::set<std::string>::iterator domain_it = handle_on_ui_thread_.begin();
domain_it != handle_on_ui_thread_.end();
@@ -94,6 +127,8 @@ void DevToolsBrowserTarget::Detach() {
handlers_.erase(handler_it);
}
+ STLDeleteValues(&handlers_);
+
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
@@ -103,11 +138,14 @@ void DevToolsBrowserTarget::Detach() {
}
DevToolsBrowserTarget::~DevToolsBrowserTarget() {
+ // DCHECK that Detach has been called or no handler has ever been registered.
+ DCHECK(handlers_.empty());
}
void DevToolsBrowserTarget::HandleCommandOnUIThread(
DevToolsProtocol::Handler* handler,
scoped_refptr<DevToolsProtocol::Command> command) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
scoped_refptr<DevToolsProtocol::Response> response =
handler->HandleCommand(command);
if (response && response->is_async_promise())
@@ -121,18 +159,19 @@ void DevToolsBrowserTarget::HandleCommandOnUIThread(
void DevToolsBrowserTarget::DeleteHandlersOnUIThread(
std::vector<DevToolsProtocol::Handler*> handlers) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
STLDeleteElements(&handlers);
}
void DevToolsBrowserTarget::Respond(const std::string& message) {
+ DCHECK_EQ(message_loop_proxy_, base::MessageLoopProxy::current());
if (!http_server_)
return;
http_server_->SendOverWebSocket(connection_id_, message);
}
void DevToolsBrowserTarget::RespondFromUIThread(const std::string& message) {
- if (!message_loop_proxy_)
- return;
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&DevToolsBrowserTarget::Respond, this, message));
diff --git a/chromium/content/browser/devtools/devtools_browser_target.h b/chromium/content/browser/devtools/devtools_browser_target.h
index 46ed291cfd7..0dda59b2ad4 100644
--- a/chromium/content/browser/devtools/devtools_browser_target.h
+++ b/chromium/content/browser/devtools/devtools_browser_target.h
@@ -13,7 +13,6 @@
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "base/stl_util.h"
#include "content/browser/devtools/devtools_protocol.h"
namespace base {
@@ -32,9 +31,7 @@ namespace content {
class DevToolsBrowserTarget
: public base::RefCountedThreadSafe<DevToolsBrowserTarget> {
public:
- DevToolsBrowserTarget(base::MessageLoopProxy* message_loop_proxy,
- net::HttpServer* server,
- int connection_id);
+ DevToolsBrowserTarget(net::HttpServer* server, int connection_id);
int connection_id() const { return connection_id_; }
@@ -61,13 +58,12 @@ class DevToolsBrowserTarget
void Respond(const std::string& message);
void RespondFromUIThread(const std::string& message);
- base::MessageLoopProxy* message_loop_proxy_;
+ scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
net::HttpServer* http_server_;
const int connection_id_;
typedef std::map<std::string, DevToolsProtocol::Handler*> DomainHandlerMap;
DomainHandlerMap handlers_;
- STLValueDeleter<DomainHandlerMap> handlers_deleter_;
std::set<std::string> handle_on_ui_thread_;
base::WeakPtrFactory<DevToolsBrowserTarget> weak_factory_;
diff --git a/chromium/content/browser/devtools/devtools_external_agent_proxy_impl.cc b/chromium/content/browser/devtools/devtools_external_agent_proxy_impl.cc
deleted file mode 100644
index 0513dc238b1..00000000000
--- a/chromium/content/browser/devtools/devtools_external_agent_proxy_impl.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/devtools/devtools_external_agent_proxy_impl.h"
-
-#include "content/browser/devtools/devtools_agent_host_impl.h"
-#include "content/browser/devtools/devtools_manager_impl.h"
-#include "content/public/browser/devtools_external_agent_proxy_delegate.h"
-
-namespace content {
-
-class DevToolsExternalAgentProxyImpl::ForwardingAgentHost
- : public DevToolsAgentHostImpl {
- public:
- ForwardingAgentHost(DevToolsExternalAgentProxyDelegate* delegate)
- : delegate_(delegate) {
- }
-
- void ConnectionClosed() {
- NotifyCloseListener();
- }
-
- private:
- virtual ~ForwardingAgentHost() {
- }
-
- // DevToolsAgentHostImpl implementation.
- virtual void Attach() OVERRIDE {
- delegate_->Attach();
- };
-
- virtual void Detach() OVERRIDE {
- delegate_->Detach();
- };
-
- virtual void DispatchOnInspectorBackend(const std::string& message) OVERRIDE {
- delegate_->SendMessageToBackend(message);
- }
-
- DevToolsExternalAgentProxyDelegate* delegate_;
-};
-
-//static
-DevToolsExternalAgentProxy* DevToolsExternalAgentProxy::Create(
- DevToolsExternalAgentProxyDelegate* delegate) {
- return new DevToolsExternalAgentProxyImpl(delegate);
-}
-
-DevToolsExternalAgentProxyImpl::DevToolsExternalAgentProxyImpl(
- DevToolsExternalAgentProxyDelegate* delegate)
- : agent_host_(new ForwardingAgentHost(delegate)) {
-}
-
-DevToolsExternalAgentProxyImpl::~DevToolsExternalAgentProxyImpl() {
-}
-
-scoped_refptr<DevToolsAgentHost> DevToolsExternalAgentProxyImpl::
- GetAgentHost() {
- return agent_host_;
-}
-
-void DevToolsExternalAgentProxyImpl::DispatchOnClientHost(
- const std::string& message) {
- DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(
- agent_host_.get(), message);
-}
-
-void DevToolsExternalAgentProxyImpl::ConnectionClosed() {
- agent_host_->ConnectionClosed();
-}
-
-} // content
diff --git a/chromium/content/browser/devtools/devtools_external_agent_proxy_impl.h b/chromium/content/browser/devtools/devtools_external_agent_proxy_impl.h
deleted file mode 100644
index cf025ec7b4f..00000000000
--- a/chromium/content/browser/devtools/devtools_external_agent_proxy_impl.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_EXTERNAL_AGENT_PROXY_IMPL_H
-#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_EXTERNAL_AGENT_PROXY_IMPL_H
-
-#include "base/memory/ref_counted.h"
-#include "content/public/browser/devtools_external_agent_proxy.h"
-
-namespace content {
-
-class DevToolsExternalAgentProxyImpl
- : public DevToolsExternalAgentProxy {
- public:
- explicit DevToolsExternalAgentProxyImpl(
- DevToolsExternalAgentProxyDelegate* delegate);
- virtual ~DevToolsExternalAgentProxyImpl();
-
- // DevToolsExternalAgentProxy implementation.
- virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() OVERRIDE;
- virtual void DispatchOnClientHost(const std::string& message) OVERRIDE;
- virtual void ConnectionClosed() OVERRIDE;
-
- private:
- class ForwardingAgentHost;
-
- scoped_refptr<ForwardingAgentHost> agent_host_;
-
- DISALLOW_COPY_AND_ASSIGN(DevToolsExternalAgentProxyImpl);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_EXTERNAL_AGENT_PROXY_IMPL_H
diff --git a/chromium/content/browser/devtools/devtools_http_handler_impl.cc b/chromium/content/browser/devtools/devtools_http_handler_impl.cc
index 1d0fca1e282..d1b5b1e6724 100644
--- a/chromium/content/browser/devtools/devtools_http_handler_impl.cc
+++ b/chromium/content/browser/devtools/devtools_http_handler_impl.cc
@@ -14,6 +14,7 @@
#include "base/logging.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
#include "base/threading/thread.h"
#include "base/values.h"
#include "content/browser/devtools/devtools_browser_target.h"
@@ -31,14 +32,15 @@
#include "content/public/browser/devtools_target.h"
#include "content/public/common/content_client.h"
#include "content/public/common/url_constants.h"
+#include "content/public/common/user_agent.h"
+#include "content/public/common/user_agent.h"
#include "grit/devtools_resources_map.h"
#include "net/base/escape.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
#include "net/server/http_server_request_info.h"
#include "net/server/http_server_response_info.h"
-#include "webkit/common/user_agent/user_agent.h"
-#include "webkit/common/user_agent/user_agent_util.h"
#if defined(OS_ANDROID)
#include "base/android/build_info.h"
@@ -48,7 +50,8 @@ namespace content {
namespace {
-const char kProtocolVersion[] = "1.0";
+const base::FilePath::CharType kDevToolsActivePortFileName[] =
+ FILE_PATH_LITERAL("DevToolsActivePort");
const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread";
@@ -56,6 +59,7 @@ const char kThumbUrlPrefix[] = "/thumb/";
const char kPageUrlPrefix[] = "/devtools/page/";
const char kTargetIdField[] = "id";
+const char kTargetParentIdField[] = "parentId";
const char kTargetTypeField[] = "type";
const char kTargetTitleField[] = "title";
const char kTargetDescriptionField[] = "description";
@@ -135,7 +139,7 @@ static bool TimeComparator(const DevToolsTarget* target1,
// static
bool DevToolsHttpHandler::IsSupportedProtocolVersion(
const std::string& version) {
- return version == kProtocolVersion;
+ return devtools::IsSupportedProtocolVersion(version);
}
// static
@@ -151,11 +155,13 @@ int DevToolsHttpHandler::GetFrontendResourceId(const std::string& name) {
DevToolsHttpHandler* DevToolsHttpHandler::Start(
const net::StreamListenSocketFactory* socket_factory,
const std::string& frontend_url,
- DevToolsHttpHandlerDelegate* delegate) {
+ DevToolsHttpHandlerDelegate* delegate,
+ const base::FilePath& active_port_output_directory) {
DevToolsHttpHandlerImpl* http_handler =
new DevToolsHttpHandlerImpl(socket_factory,
frontend_url,
- delegate);
+ delegate,
+ active_port_output_directory);
http_handler->Start();
return http_handler;
}
@@ -215,8 +221,7 @@ GURL DevToolsHttpHandlerImpl::GetFrontendURL() {
net::IPEndPoint ip_address;
if (server_->GetLocalAddress(&ip_address))
return GURL();
- return GURL(std::string("http://") + ip_address.ToString() +
- overridden_frontend_url_);
+ return GURL(std::string("http://") + ip_address.ToString() + frontend_url_);
}
static std::string PathWithoutParams(const std::string& path) {
@@ -237,7 +242,12 @@ static std::string GetMimeType(const std::string& filename) {
return "image/png";
} else if (EndsWith(filename, ".gif", false)) {
return "image/gif";
+ } else if (EndsWith(filename, ".json", false)) {
+ return "application/json";
}
+ LOG(ERROR) << "GetMimeType doesn't know mime type for: "
+ << filename
+ << " text/plain will be returned";
NOTREACHED();
return "text/plain";
}
@@ -262,7 +272,7 @@ void DevToolsHttpHandlerImpl::OnHttpRequest(
DevToolsTarget* target = GetTarget(target_id);
GURL page_url;
if (target)
- page_url = target->GetUrl();
+ page_url = target->GetURL();
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
@@ -318,24 +328,21 @@ void DevToolsHttpHandlerImpl::OnWebSocketRequest(
std::string browser_prefix = "/devtools/browser";
size_t browser_pos = request.path.find(browser_prefix);
if (browser_pos == 0) {
- if (browser_target_) {
- server_->Send500(connection_id, "Another client already attached");
- return;
- }
- browser_target_ = new DevToolsBrowserTarget(
- thread_->message_loop_proxy().get(), server_.get(), connection_id);
- browser_target_->RegisterDomainHandler(
+ scoped_refptr<DevToolsBrowserTarget> browser_target =
+ new DevToolsBrowserTarget(server_.get(), connection_id);
+ browser_target->RegisterDomainHandler(
devtools::Tracing::kName,
- new DevToolsTracingHandler(),
+ new DevToolsTracingHandler(DevToolsTracingHandler::Browser),
true /* handle on UI thread */);
- browser_target_->RegisterDomainHandler(
+ browser_target->RegisterDomainHandler(
TetheringHandler::kDomain,
new TetheringHandler(delegate_.get()),
false /* handle on this thread */);
- browser_target_->RegisterDomainHandler(
+ browser_target->RegisterDomainHandler(
devtools::SystemInfo::kName,
new DevToolsSystemInfoHandler(),
true /* handle on UI thread */);
+ browser_targets_[connection_id] = browser_target;
server_->AcceptWebSocket(connection_id, request);
return;
@@ -354,8 +361,9 @@ void DevToolsHttpHandlerImpl::OnWebSocketRequest(
void DevToolsHttpHandlerImpl::OnWebSocketMessage(
int connection_id,
const std::string& data) {
- if (browser_target_ && connection_id == browser_target_->connection_id()) {
- browser_target_->HandleMessage(data);
+ BrowserTargets::iterator it = browser_targets_.find(connection_id);
+ if (it != browser_targets_.end()) {
+ it->second->HandleMessage(data);
return;
}
@@ -370,9 +378,10 @@ void DevToolsHttpHandlerImpl::OnWebSocketMessage(
}
void DevToolsHttpHandlerImpl::OnClose(int connection_id) {
- if (browser_target_ && browser_target_->connection_id() == connection_id) {
- browser_target_->Detach();
- browser_target_ = NULL;
+ BrowserTargets::iterator it = browser_targets_.find(connection_id);
+ if (it != browser_targets_.end()) {
+ it->second->Detach();
+ browser_targets_.erase(it);
return;
}
@@ -390,8 +399,8 @@ std::string DevToolsHttpHandlerImpl::GetFrontendURLInternal(
const std::string& host) {
return base::StringPrintf(
"%s%sws=%s%s%s",
- overridden_frontend_url_.c_str(),
- overridden_frontend_url_.find("?") == std::string::npos ? "?" : "&",
+ frontend_url_.c_str(),
+ frontend_url_.find("?") == std::string::npos ? "?" : "&",
host.c_str(),
kPageUrlPrefix,
id.c_str());
@@ -452,11 +461,10 @@ void DevToolsHttpHandlerImpl::OnJsonRequestUI(
if (command == "version") {
base::DictionaryValue version;
- version.SetString("Protocol-Version", kProtocolVersion);
- version.SetString("WebKit-Version", webkit_glue::GetWebKitVersion());
- version.SetString("Browser", content::GetContentClient()->GetProduct());
- version.SetString("User-Agent",
- webkit_glue::GetUserAgent(GURL(kAboutBlankURL)));
+ version.SetString("Protocol-Version", devtools::kProtocolVersion);
+ version.SetString("WebKit-Version", GetWebKitVersion());
+ version.SetString("Browser", GetContentClient()->GetProduct());
+ version.SetString("User-Agent", GetContentClient()->GetUserAgent());
#if defined(OS_ANDROID)
version.SetString("Android-Package",
base::android::BuildInfo::GetInstance()->package_name());
@@ -478,7 +486,7 @@ void DevToolsHttpHandlerImpl::OnJsonRequestUI(
GURL url(net::UnescapeURLComponent(
query, net::UnescapeRule::URL_SPECIAL_CHARS));
if (!url.is_valid())
- url = GURL(kAboutBlankURL);
+ url = GURL(url::kAboutBlankURL);
scoped_ptr<DevToolsTarget> target(delegate_->CreateNewTarget(url));
if (!target) {
SendJson(connection_id,
@@ -641,12 +649,14 @@ void DevToolsHttpHandlerImpl::OnCloseUI(int connection_id) {
DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl(
const net::StreamListenSocketFactory* socket_factory,
const std::string& frontend_url,
- DevToolsHttpHandlerDelegate* delegate)
- : overridden_frontend_url_(frontend_url),
+ DevToolsHttpHandlerDelegate* delegate,
+ const base::FilePath& active_port_output_directory)
+ : frontend_url_(frontend_url),
socket_factory_(socket_factory),
- delegate_(delegate) {
- if (overridden_frontend_url_.empty())
- overridden_frontend_url_ = "/devtools/devtools.html";
+ delegate_(delegate),
+ active_port_output_directory_(active_port_output_directory) {
+ if (frontend_url_.empty())
+ frontend_url_ = "/devtools/devtools.html";
// Balanced in ResetHandlerThreadAndRelease().
AddRef();
@@ -655,6 +665,8 @@ DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl(
// Runs on the handler thread
void DevToolsHttpHandlerImpl::Init() {
server_ = new net::HttpServer(*socket_factory_.get(), this);
+ if (!active_port_output_directory_.empty())
+ WriteActivePortToUserProfile();
}
// Runs on the handler thread
@@ -674,6 +686,25 @@ void DevToolsHttpHandlerImpl::StopHandlerThread() {
thread_->Stop();
}
+void DevToolsHttpHandlerImpl::WriteActivePortToUserProfile() {
+ DCHECK(!active_port_output_directory_.empty());
+ net::IPEndPoint endpoint;
+ int err;
+ if ((err = server_->GetLocalAddress(&endpoint)) != net::OK) {
+ LOG(ERROR) << "Error " << err << " getting local address";
+ return;
+ }
+
+ // Write this port to a well-known file in the profile directory
+ // so Telemetry can pick it up.
+ base::FilePath path = active_port_output_directory_.Append(
+ kDevToolsActivePortFileName);
+ std::string port_string = base::IntToString(endpoint.port());
+ if (base::WriteFile(path, port_string.c_str(), port_string.length()) < 0) {
+ LOG(ERROR) << "Error writing DevTools active port to file";
+ }
+}
+
void DevToolsHttpHandlerImpl::SendJson(int connection_id,
net::HttpStatusCode status_code,
base::Value* value,
@@ -753,15 +784,18 @@ base::DictionaryValue* DevToolsHttpHandlerImpl::SerializeTarget(
std::string id = target.GetId();
dictionary->SetString(kTargetIdField, id);
+ std::string parent_id = target.GetParentId();
+ if (!parent_id.empty())
+ dictionary->SetString(kTargetParentIdField, parent_id);
dictionary->SetString(kTargetTypeField, target.GetType());
dictionary->SetString(kTargetTitleField,
net::EscapeForHTML(target.GetTitle()));
dictionary->SetString(kTargetDescriptionField, target.GetDescription());
- GURL url = target.GetUrl();
+ GURL url = target.GetURL();
dictionary->SetString(kTargetUrlField, url.spec());
- GURL favicon_url = target.GetFaviconUrl();
+ GURL favicon_url = target.GetFaviconURL();
if (favicon_url.is_valid())
dictionary->SetString(kTargetFaviconUrlField, favicon_url.spec());
diff --git a/chromium/content/browser/devtools/devtools_http_handler_impl.h b/chromium/content/browser/devtools/devtools_http_handler_impl.h
index 4e40db07f11..0d08d9897aa 100644
--- a/chromium/content/browser/devtools/devtools_http_handler_impl.h
+++ b/chromium/content/browser/devtools/devtools_http_handler_impl.h
@@ -46,7 +46,8 @@ class DevToolsHttpHandlerImpl
// Takes ownership over |socket_factory|.
DevToolsHttpHandlerImpl(const net::StreamListenSocketFactory* socket_factory,
const std::string& frontend_url,
- DevToolsHttpHandlerDelegate* delegate);
+ DevToolsHttpHandlerDelegate* delegate,
+ const base::FilePath& active_port_output_directory);
virtual ~DevToolsHttpHandlerImpl();
void Start();
@@ -90,6 +91,8 @@ class DevToolsHttpHandlerImpl
void StartHandlerThread();
void StopHandlerThread();
+ void WriteActivePortToUserProfile();
+
void SendJson(int connection_id,
net::HttpStatusCode status_code,
base::Value* value,
@@ -113,15 +116,17 @@ class DevToolsHttpHandlerImpl
// The thread used by the devtools handler to run server socket.
scoped_ptr<base::Thread> thread_;
- std::string overridden_frontend_url_;
+ std::string frontend_url_;
scoped_ptr<const net::StreamListenSocketFactory> socket_factory_;
scoped_refptr<net::HttpServer> server_;
typedef std::map<int, DevToolsClientHost*> ConnectionToClientHostMap;
ConnectionToClientHostMap connection_to_client_host_ui_;
scoped_ptr<DevToolsHttpHandlerDelegate> delegate_;
+ base::FilePath active_port_output_directory_;
typedef std::map<std::string, DevToolsTarget*> TargetMap;
TargetMap target_map_;
- scoped_refptr<DevToolsBrowserTarget> browser_target_;
+ typedef std::map<int, scoped_refptr<DevToolsBrowserTarget> > BrowserTargets;
+ BrowserTargets browser_targets_;
DISALLOW_COPY_AND_ASSIGN(DevToolsHttpHandlerImpl);
};
diff --git a/chromium/content/browser/devtools/devtools_http_handler_unittest.cc b/chromium/content/browser/devtools/devtools_http_handler_unittest.cc
index f3179f0f140..88710924c2a 100644
--- a/chromium/content/browser/devtools/devtools_http_handler_unittest.cc
+++ b/chromium/content/browser/devtools/devtools_http_handler_unittest.cc
@@ -2,25 +2,34 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/file_util.h"
+#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/strings/string_number_conversions.h"
#include "content/browser/browser_thread_impl.h"
#include "content/public/browser/devtools_http_handler.h"
#include "content/public/browser/devtools_http_handler_delegate.h"
#include "content/public/browser/devtools_target.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
#include "net/socket/stream_listen_socket.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace {
+const int kDummyPort = 4321;
+const base::FilePath::CharType kDevToolsActivePortFileName[] =
+ FILE_PATH_LITERAL("DevToolsActivePort");
+
using net::StreamListenSocket;
class DummyListenSocket : public StreamListenSocket,
public StreamListenSocket::Delegate {
public:
DummyListenSocket()
- : StreamListenSocket(0, this) {}
+ : StreamListenSocket(net::kInvalidSocket, this) {}
// StreamListenSocket::Delegate "implementation"
virtual void DidAccept(StreamListenSocket* server,
@@ -32,6 +41,12 @@ class DummyListenSocket : public StreamListenSocket,
protected:
virtual ~DummyListenSocket() {}
virtual void Accept() OVERRIDE {}
+ virtual int GetLocalAddress(net::IPEndPoint* address) OVERRIDE {
+ net::IPAddressNumber number;
+ EXPECT_TRUE(net::ParseIPLiteralToNumber("127.0.0.1", &number));
+ *address = net::IPEndPoint(number, kDummyPort);
+ return net::OK;
+ }
};
class DummyListenSocketFactory : public net::StreamListenSocketFactory {
@@ -106,7 +121,8 @@ TEST_F(DevToolsHttpHandlerTest, TestStartStop) {
new DummyListenSocketFactory(run_loop.QuitClosure(),
run_loop_2.QuitClosure()),
std::string(),
- new DummyDelegate());
+ new DummyDelegate(),
+ base::FilePath());
// Our dummy socket factory will post a quit message once the server will
// become ready.
run_loop.Run();
@@ -115,4 +131,34 @@ TEST_F(DevToolsHttpHandlerTest, TestStartStop) {
run_loop_2.Run();
}
+TEST_F(DevToolsHttpHandlerTest, TestDevToolsActivePort) {
+ base::RunLoop run_loop, run_loop_2;
+ base::ScopedTempDir temp_dir;
+ EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
+ content::DevToolsHttpHandler* devtools_http_handler_ =
+ content::DevToolsHttpHandler::Start(
+ new DummyListenSocketFactory(run_loop.QuitClosure(),
+ run_loop_2.QuitClosure()),
+ std::string(),
+ new DummyDelegate(),
+ temp_dir.path());
+ // Our dummy socket factory will post a quit message once the server will
+ // become ready.
+ run_loop.Run();
+ devtools_http_handler_->Stop();
+ // Make sure the handler actually stops.
+ run_loop_2.Run();
+
+ // Now make sure the DevToolsActivePort was written into the
+ // temporary directory and its contents are as expected.
+ base::FilePath active_port_file = temp_dir.path().Append(
+ kDevToolsActivePortFileName);
+ EXPECT_TRUE(base::PathExists(active_port_file));
+ std::string file_contents;
+ EXPECT_TRUE(base::ReadFileToString(active_port_file, &file_contents));
+ int port = 0;
+ EXPECT_TRUE(base::StringToInt(file_contents, &port));
+ EXPECT_EQ(kDummyPort, port);
+}
+
} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_manager_impl.cc b/chromium/content/browser/devtools/devtools_manager_impl.cc
index 56b2dd7d2f4..3aafd1c2e2e 100644
--- a/chromium/content/browser/devtools/devtools_manager_impl.cc
+++ b/chromium/content/browser/devtools/devtools_manager_impl.cc
@@ -13,7 +13,9 @@
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/devtools_client_host.h"
+#include "content/public/browser/devtools_manager_delegate.h"
namespace content {
@@ -27,7 +29,8 @@ DevToolsManagerImpl* DevToolsManagerImpl::GetInstance() {
return Singleton<DevToolsManagerImpl>::get();
}
-DevToolsManagerImpl::DevToolsManagerImpl() {
+DevToolsManagerImpl::DevToolsManagerImpl()
+ : delegate_(GetContentClient()->browser()->GetDevToolsManagerDelegate()) {
}
DevToolsManagerImpl::~DevToolsManagerImpl() {
@@ -35,6 +38,12 @@ DevToolsManagerImpl::~DevToolsManagerImpl() {
DCHECK(client_to_agent_host_.empty());
}
+void DevToolsManagerImpl::Inspect(BrowserContext* browser_context,
+ DevToolsAgentHost* agent_host) {
+ if (delegate_)
+ delegate_->Inspect(browser_context, agent_host);
+}
+
DevToolsClientHost* DevToolsManagerImpl::GetDevToolsClientHostFor(
DevToolsAgentHostImpl* agent_host_impl) {
AgentToClientHostMap::iterator it =
@@ -184,6 +193,8 @@ void DevToolsManagerImpl::RemoveAgentStateCallback(const Callback& callback) {
void DevToolsManagerImpl::NotifyObservers(DevToolsAgentHost* agent_host,
bool attached) {
CallbackContainer copy(callbacks_);
+ if (delegate_)
+ delegate_->DevToolsAgentStateChanged(agent_host, attached);
for (CallbackContainer::iterator it = copy.begin(); it != copy.end(); ++it)
(*it)->Run(agent_host, attached);
}
diff --git a/chromium/content/browser/devtools/devtools_manager_impl.h b/chromium/content/browser/devtools/devtools_manager_impl.h
index a14b2f1ca11..19b6918518b 100644
--- a/chromium/content/browser/devtools/devtools_manager_impl.h
+++ b/chromium/content/browser/devtools/devtools_manager_impl.h
@@ -24,6 +24,8 @@ class Message;
namespace content {
+class BrowserContext;
+class DevToolsManagerDelegate;
class RenderViewHost;
// This class is a singleton that manages DevToolsClientHost instances and
@@ -43,9 +45,14 @@ class CONTENT_EXPORT DevToolsManagerImpl
DevToolsManagerImpl();
virtual ~DevToolsManagerImpl();
+ // Opens the inspector for |agent_host|.
+ void Inspect(BrowserContext* browser_context, DevToolsAgentHost* agent_host);
+
void DispatchOnInspectorFrontend(DevToolsAgentHost* agent_host,
const std::string& message);
+ DevToolsManagerDelegate* delegate() const { return delegate_.get(); }
+
// DevToolsManager implementation
virtual bool DispatchOnInspectorBackend(DevToolsClientHost* from,
const std::string& message) OVERRIDE;
@@ -96,6 +103,8 @@ class CONTENT_EXPORT DevToolsManagerImpl
typedef std::vector<const Callback*> CallbackContainer;
CallbackContainer callbacks_;
+ scoped_ptr<DevToolsManagerDelegate> delegate_;
+
DISALLOW_COPY_AND_ASSIGN(DevToolsManagerImpl);
};
diff --git a/chromium/content/browser/devtools/devtools_manager_unittest.cc b/chromium/content/browser/devtools/devtools_manager_unittest.cc
index aac9b6cbb92..75c527388b4 100644
--- a/chromium/content/browser/devtools/devtools_manager_unittest.cc
+++ b/chromium/content/browser/devtools/devtools_manager_unittest.cc
@@ -216,7 +216,7 @@ class TestExternalAgentDelegate: public DevToolsExternalAgentProxyDelegate {
EXPECT_EQ(count, event_counter_[name]);
}
- virtual void Attach() OVERRIDE {
+ virtual void Attach(DevToolsExternalAgentProxy* proxy) OVERRIDE {
recordEvent("Attach");
};
@@ -239,12 +239,10 @@ class TestExternalAgentDelegate: public DevToolsExternalAgentProxyDelegate {
};
TEST_F(DevToolsManagerTest, TestExternalProxy) {
- TestExternalAgentDelegate delegate;
+ TestExternalAgentDelegate* delegate = new TestExternalAgentDelegate();
- scoped_ptr<DevToolsExternalAgentProxy> proxy(
- DevToolsExternalAgentProxy::Create(&delegate));
-
- scoped_refptr<DevToolsAgentHost> agent_host = proxy->GetAgentHost();
+ scoped_refptr<DevToolsAgentHost> agent_host =
+ DevToolsAgentHost::Create(delegate);
EXPECT_EQ(agent_host, DevToolsAgentHost::GetForId(agent_host->GetId()));
DevToolsManager* manager = DevToolsManager::GetInstance();
diff --git a/chromium/content/browser/devtools/devtools_netlog_observer.cc b/chromium/content/browser/devtools/devtools_netlog_observer.cc
index 21a835b9e99..27ce58ae49b 100644
--- a/chromium/content/browser/devtools/devtools_netlog_observer.cc
+++ b/chromium/content/browser/devtools/devtools_netlog_observer.cc
@@ -42,10 +42,6 @@ void DevToolsNetLogObserver::OnAddEntry(const net::NetLog::Entry& entry) {
if (entry.source().type == net::NetLog::SOURCE_URL_REQUEST)
OnAddURLRequestEntry(entry);
- else if (entry.source().type == net::NetLog::SOURCE_HTTP_STREAM_JOB)
- OnAddHTTPStreamJobEntry(entry);
- else if (entry.source().type == net::NetLog::SOURCE_SOCKET)
- OnAddSocketEntry(entry);
}
void DevToolsNetLogObserver::OnAddURLRequestEntry(
@@ -74,22 +70,12 @@ void DevToolsNetLogObserver::OnAddURLRequestEntry(
}
request_to_info_[entry.source().id] = new ResourceInfo();
-
- if (request_to_encoded_data_length_.size() > kMaxNumEntries) {
- LOG(WARNING) << "The encoded data length observer url request count "
- "has grown larger than expected, resetting";
- request_to_encoded_data_length_.clear();
- }
-
- request_to_encoded_data_length_[entry.source().id] = 0;
}
return;
} else if (entry.type() == net::NetLog::TYPE_REQUEST_ALIVE) {
// Cleanup records based on the TYPE_REQUEST_ALIVE entry.
- if (is_end) {
+ if (is_end)
request_to_info_.erase(entry.source().id);
- request_to_encoded_data_length_.erase(entry.source().id);
- }
return;
}
@@ -162,35 +148,15 @@ void DevToolsNetLogObserver::OnAddURLRequestEntry(
response_headers->EnumerateHeaderLines(&it, &name, &value); ) {
info->response_headers.push_back(std::make_pair(name, value));
}
- info->response_headers_text =
- net::HttpUtil::ConvertHeadersBackToHTTPResponse(
- response_headers->raw_headers());
- break;
- }
- case net::NetLog::TYPE_HTTP_STREAM_REQUEST_BOUND_TO_JOB: {
- scoped_ptr<base::Value> event_params(entry.ParametersToValue());
- net::NetLog::Source http_stream_job_source;
- if (!net::NetLog::Source::FromEventParameters(event_params.get(),
- &http_stream_job_source)) {
- NOTREACHED();
- break;
- }
- uint32 http_stream_job_id = http_stream_job_source.id;
- HTTPStreamJobToSocketMap::iterator it =
- http_stream_job_to_socket_.find(http_stream_job_id);
- if (it == http_stream_job_to_socket_.end())
- return;
- uint32 socket_id = it->second;
-
- if (socket_to_request_.size() > kMaxNumEntries) {
- LOG(WARNING) << "The url request observer socket count has grown "
- "larger than expected, resetting";
- socket_to_request_.clear();
+ if (!info->request_headers_text.empty()) {
+ info->response_headers_text =
+ net::HttpUtil::ConvertHeadersBackToHTTPResponse(
+ response_headers->raw_headers());
+ } else {
+ // SPDY request.
+ info->response_headers_text = "";
}
-
- socket_to_request_[socket_id] = entry.source().id;
- http_stream_job_to_socket_.erase(http_stream_job_id);
break;
}
default:
@@ -198,68 +164,6 @@ void DevToolsNetLogObserver::OnAddURLRequestEntry(
}
}
-void DevToolsNetLogObserver::OnAddHTTPStreamJobEntry(
- const net::NetLog::Entry& entry) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- if (entry.type() == net::NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET) {
- scoped_ptr<base::Value> event_params(entry.ParametersToValue());
- net::NetLog::Source socket_source;
- if (!net::NetLog::Source::FromEventParameters(event_params.get(),
- &socket_source)) {
- NOTREACHED();
- return;
- }
-
- // Prevents us from passively growing the memory unbounded in
- // case something went wrong. Should not happen.
- if (http_stream_job_to_socket_.size() > kMaxNumEntries) {
- LOG(WARNING) << "The load timing observer http stream job count "
- "has grown larger than expected, resetting";
- http_stream_job_to_socket_.clear();
- }
- http_stream_job_to_socket_[entry.source().id] = socket_source.id;
- }
-}
-
-void DevToolsNetLogObserver::OnAddSocketEntry(
- const net::NetLog::Entry& entry) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- bool is_end = entry.phase() == net::NetLog::PHASE_END;
-
- SocketToRequestMap::iterator it =
- socket_to_request_.find(entry.source().id);
- if (it == socket_to_request_.end())
- return;
- uint32 request_id = it->second;
-
- if (entry.type() == net::NetLog::TYPE_SOCKET_IN_USE) {
- if (is_end)
- socket_to_request_.erase(entry.source().id);
- return;
- }
-
- RequestToEncodedDataLengthMap::iterator encoded_data_length_it =
- request_to_encoded_data_length_.find(request_id);
- if (encoded_data_length_it == request_to_encoded_data_length_.end())
- return;
-
- if (net::NetLog::TYPE_SOCKET_BYTES_RECEIVED == entry.type()) {
- int byte_count = 0;
- scoped_ptr<base::Value> value(entry.ParametersToValue());
- if (!value->IsType(base::Value::TYPE_DICTIONARY))
- return;
-
- base::DictionaryValue* dValue =
- static_cast<base::DictionaryValue*>(value.get());
- if (!dValue->GetInteger("byte_count", &byte_count))
- return;
-
- encoded_data_length_it->second += byte_count;
- }
-}
-
void DevToolsNetLogObserver::Attach() {
DCHECK(!instance_);
net::NetLog* net_log = GetContentClient()->browser()->GetNetLog();
@@ -303,26 +207,4 @@ void DevToolsNetLogObserver::PopulateResponseInfo(
dev_tools_net_log_observer->GetResourceInfo(source_id);
}
-// static
-int DevToolsNetLogObserver::GetAndResetEncodedDataLength(
- net::URLRequest* request) {
- if (!(request->load_flags() & net::LOAD_REPORT_RAW_HEADERS))
- return -1;
-
- uint32 source_id = request->net_log().source().id;
- DevToolsNetLogObserver* dev_tools_net_log_observer =
- DevToolsNetLogObserver::GetInstance();
- if (dev_tools_net_log_observer == NULL)
- return -1;
-
- RequestToEncodedDataLengthMap::iterator it =
- dev_tools_net_log_observer->request_to_encoded_data_length_.find(
- source_id);
- if (it == dev_tools_net_log_observer->request_to_encoded_data_length_.end())
- return -1;
- int encoded_data_length = it->second;
- it->second = 0;
- return encoded_data_length;
-}
-
} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_netlog_observer.h b/chromium/content/browser/devtools/devtools_netlog_observer.h
index d1d478c3791..f063a3d432c 100644
--- a/chromium/content/browser/devtools/devtools_netlog_observer.h
+++ b/chromium/content/browser/devtools/devtools_netlog_observer.h
@@ -7,8 +7,8 @@
#include "base/containers/hash_tables.h"
#include "base/memory/ref_counted.h"
+#include "content/public/common/resource_devtools_info.h"
#include "net/base/net_log.h"
-#include "webkit/common/resource_devtools_info.h"
namespace net {
class URLRequest;
@@ -25,15 +25,13 @@ struct ResourceResponse;
// IO Thread, it must also reside on the IO Thread. Only OnAddEntry can be
// called from other threads.
class DevToolsNetLogObserver : public net::NetLog::ThreadSafeObserver {
- typedef webkit_glue::ResourceDevToolsInfo ResourceInfo;
+ typedef ResourceDevToolsInfo ResourceInfo;
public:
// net::NetLog::ThreadSafeObserver implementation:
virtual void OnAddEntry(const net::NetLog::Entry& entry) OVERRIDE;
void OnAddURLRequestEntry(const net::NetLog::Entry& entry);
- void OnAddHTTPStreamJobEntry(const net::NetLog::Entry& entry);
- void OnAddSocketEntry(const net::NetLog::Entry& entry);
static void Attach();
static void Detach();
@@ -43,7 +41,6 @@ class DevToolsNetLogObserver : public net::NetLog::ThreadSafeObserver {
static DevToolsNetLogObserver* GetInstance();
static void PopulateResponseInfo(net::URLRequest*,
ResourceResponse*);
- static int GetAndResetEncodedDataLength(net::URLRequest* request);
private:
static DevToolsNetLogObserver* instance_;
@@ -54,13 +51,7 @@ class DevToolsNetLogObserver : public net::NetLog::ThreadSafeObserver {
ResourceInfo* GetResourceInfo(uint32 id);
typedef base::hash_map<uint32, scoped_refptr<ResourceInfo> > RequestToInfoMap;
- typedef base::hash_map<uint32, int> RequestToEncodedDataLengthMap;
- typedef base::hash_map<uint32, uint32> HTTPStreamJobToSocketMap;
- typedef base::hash_map<uint32, uint32> SocketToRequestMap;
RequestToInfoMap request_to_info_;
- RequestToEncodedDataLengthMap request_to_encoded_data_length_;
- HTTPStreamJobToSocketMap http_stream_job_to_socket_;
- SocketToRequestMap socket_to_request_;
DISALLOW_COPY_AND_ASSIGN(DevToolsNetLogObserver);
};
diff --git a/chromium/content/browser/devtools/devtools_power_handler.cc b/chromium/content/browser/devtools/devtools_power_handler.cc
new file mode 100644
index 00000000000..43772b47607
--- /dev/null
+++ b/chromium/content/browser/devtools/devtools_power_handler.cc
@@ -0,0 +1,83 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/devtools/devtools_power_handler.h"
+
+#include "base/bind.h"
+#include "base/values.h"
+#include "content/browser/devtools/devtools_protocol_constants.h"
+#include "content/browser/power_profiler/power_profiler_service.h"
+
+namespace content {
+
+DevToolsPowerHandler::DevToolsPowerHandler() {
+ RegisterCommandHandler(devtools::Power::start::kName,
+ base::Bind(&DevToolsPowerHandler::OnStart,
+ base::Unretained(this)));
+ RegisterCommandHandler(devtools::Power::end::kName,
+ base::Bind(&DevToolsPowerHandler::OnEnd,
+ base::Unretained(this)));
+ RegisterCommandHandler(devtools::Power::canProfilePower::kName,
+ base::Bind(&DevToolsPowerHandler::OnCanProfilePower,
+ base::Unretained(this)));
+}
+
+DevToolsPowerHandler::~DevToolsPowerHandler() {
+ PowerProfilerService::GetInstance()->RemoveObserver(this);
+}
+
+void DevToolsPowerHandler::OnPowerEvent(const PowerEventVector& events) {
+ base::DictionaryValue* params = new base::DictionaryValue();
+ base::ListValue* event_list = new base::ListValue();
+
+ std::vector<PowerEvent>::const_iterator iter;
+ for (iter = events.begin(); iter != events.end(); ++iter) {
+ base::DictionaryValue* event_body = new base::DictionaryValue();
+
+ DCHECK(iter->type < PowerEvent::ID_COUNT);
+ event_body->SetString("type", kPowerTypeNames[iter->type]);
+ // Use internal value to be consistent with Blink's
+ // monotonicallyIncreasingTime.
+ event_body->SetDouble("timestamp", iter->time.ToInternalValue() /
+ static_cast<double>(base::Time::kMicrosecondsPerMillisecond));
+ event_body->SetDouble("value", iter->value);
+ event_list->Append(event_body);
+ }
+
+ params->Set(devtools::Power::dataAvailable::kParamValue, event_list);
+ SendNotification(devtools::Power::dataAvailable::kName, params);
+}
+
+scoped_refptr<DevToolsProtocol::Response>
+DevToolsPowerHandler::OnStart(
+ scoped_refptr<DevToolsProtocol::Command> command) {
+ if (PowerProfilerService::GetInstance()->IsAvailable()) {
+ PowerProfilerService::GetInstance()->AddObserver(this);
+ return command->SuccessResponse(NULL);
+ }
+
+ return command->InternalErrorResponse("Power profiler service unavailable");
+}
+
+scoped_refptr<DevToolsProtocol::Response>
+DevToolsPowerHandler::OnEnd(scoped_refptr<DevToolsProtocol::Command> command) {
+ if (PowerProfilerService::GetInstance()->IsAvailable()) {
+ PowerProfilerService::GetInstance()->RemoveObserver(this);
+ return command->SuccessResponse(NULL);
+ }
+
+ return command->InternalErrorResponse("Power profiler service unavailable");
+}
+
+scoped_refptr<DevToolsProtocol::Response>
+DevToolsPowerHandler::OnCanProfilePower(
+ scoped_refptr<DevToolsProtocol::Command> command) {
+ base::DictionaryValue* result = new base::DictionaryValue();
+ result->SetBoolean(devtools::kResult,
+ PowerProfilerService::GetInstance()->IsAvailable());
+
+ return command->SuccessResponse(result);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_power_handler.h b/chromium/content/browser/devtools/devtools_power_handler.h
new file mode 100644
index 00000000000..f645392a199
--- /dev/null
+++ b/chromium/content/browser/devtools/devtools_power_handler.h
@@ -0,0 +1,38 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_POWER_HANDLER_H_
+#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_POWER_HANDLER_H_
+
+#include "base/time/time.h"
+#include "content/browser/devtools/devtools_protocol.h"
+#include "content/browser/power_profiler/power_profiler_observer.h"
+
+namespace content {
+
+// This class provides power information to DevTools.
+class DevToolsPowerHandler
+ : public DevToolsProtocol::Handler,
+ public PowerProfilerObserver {
+ public:
+ DevToolsPowerHandler();
+ virtual ~DevToolsPowerHandler();
+
+ // PowerProfilerObserver override.
+ virtual void OnPowerEvent(const PowerEventVector&) OVERRIDE;
+
+ private:
+ scoped_refptr<DevToolsProtocol::Response> OnStart(
+ scoped_refptr<DevToolsProtocol::Command> command);
+ scoped_refptr<DevToolsProtocol::Response> OnEnd(
+ scoped_refptr<DevToolsProtocol::Command> command);
+ scoped_refptr<DevToolsProtocol::Response> OnCanProfilePower(
+ scoped_refptr<DevToolsProtocol::Command> command);
+
+ DISALLOW_COPY_AND_ASSIGN(DevToolsPowerHandler);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_POWER_HANDLER_H_
diff --git a/chromium/content/browser/devtools/devtools_protocol.cc b/chromium/content/browser/devtools/devtools_protocol.cc
index e0e544e54c4..5e127f1dcba 100644
--- a/chromium/content/browser/devtools/devtools_protocol.cc
+++ b/chromium/content/browser/devtools/devtools_protocol.cc
@@ -27,7 +27,8 @@ enum Error {
kErrorInvalidRequest = -32600,
kErrorNoSuchMethod = -32601,
kErrorInvalidParams = -32602,
- kErrorInternalError = -32603
+ kErrorInternalError = -32603,
+ kErrorServerError = -32000
};
} // namespace
@@ -84,6 +85,11 @@ DevToolsProtocol::Command::NoSuchMethodErrorResponse() {
}
scoped_refptr<DevToolsProtocol::Response>
+DevToolsProtocol::Command::ServerErrorResponse(const std::string& message) {
+ return new Response(id_, kErrorServerError, message);
+}
+
+scoped_refptr<DevToolsProtocol::Response>
DevToolsProtocol::Command::AsyncResponsePromise() {
scoped_refptr<DevToolsProtocol::Response> promise =
new DevToolsProtocol::Response(0, NULL);
@@ -216,13 +222,20 @@ scoped_refptr<DevToolsProtocol::Command> DevToolsProtocol::ParseCommand(
std::string* error_response) {
scoped_ptr<base::DictionaryValue> command_dict(
ParseMessage(json, error_response));
+ return ParseCommand(command_dict.get(), error_response);
+}
+
+// static
+scoped_refptr<DevToolsProtocol::Command> DevToolsProtocol::ParseCommand(
+ base::DictionaryValue* command_dict,
+ std::string* error_response) {
if (!command_dict)
return NULL;
int id;
std::string method;
bool ok = command_dict->GetInteger(kIdParam, &id) && id >= 0;
- ok = ok && ParseMethod(command_dict.get(), &method);
+ ok = ok && ParseMethod(command_dict, &method);
if (!ok) {
scoped_refptr<Response> response =
new Response(kNoId, kErrorInvalidRequest, "No such method");
@@ -244,6 +257,28 @@ DevToolsProtocol::CreateCommand(
return new Command(id, method, params);
}
+//static
+scoped_refptr<DevToolsProtocol::Response>
+DevToolsProtocol::ParseResponse(
+ base::DictionaryValue* response_dict) {
+ int id;
+ if (!response_dict->GetInteger(kIdParam, &id))
+ id = kNoId;
+
+ const base::DictionaryValue* error_dict;
+ if (response_dict->GetDictionary(kErrorParam, &error_dict)) {
+ int error_code = kErrorInternalError;
+ response_dict->GetInteger(kErrorCodeParam, &error_code);
+ std::string error_message;
+ response_dict->GetString(kErrorMessageParam, &error_message);
+ return new Response(id, error_code, error_message);
+ }
+
+ const base::DictionaryValue* result = NULL;
+ response_dict->GetDictionary(kResultParam, &result);
+ return new Response(id, result ? result->DeepCopy() : NULL);
+}
+
// static
scoped_refptr<DevToolsProtocol::Notification>
DevToolsProtocol::ParseNotification(const std::string& json) {
@@ -275,11 +310,11 @@ base::DictionaryValue* DevToolsProtocol::ParseMessage(
std::string* error_response) {
int parse_error_code;
std::string error_message;
- scoped_ptr<Value> message(
+ scoped_ptr<base::Value> message(
base::JSONReader::ReadAndReturnError(
json, 0, &parse_error_code, &error_message));
- if (!message || !message->IsType(Value::TYPE_DICTIONARY)) {
+ if (!message || !message->IsType(base::Value::TYPE_DICTIONARY)) {
scoped_refptr<Response> response =
new Response(0, kErrorParseError, error_message);
if (error_response)
diff --git a/chromium/content/browser/devtools/devtools_protocol.h b/chromium/content/browser/devtools/devtools_protocol.h
index 15b0a8087be..cbc075b3715 100644
--- a/chromium/content/browser/devtools/devtools_protocol.h
+++ b/chromium/content/browser/devtools/devtools_protocol.h
@@ -64,6 +64,9 @@ class DevToolsProtocol {
// Creates error response.
scoped_refptr<Response> NoSuchMethodErrorResponse();
+ // Creates error response.
+ scoped_refptr<Response> ServerErrorResponse(const std::string& message);
+
// Creates async response promise.
scoped_refptr<Response> AsyncResponsePromise();
@@ -157,25 +160,32 @@ class DevToolsProtocol {
DISALLOW_COPY_AND_ASSIGN(Handler);
};
+ CONTENT_EXPORT static base::DictionaryValue* ParseMessage(
+ const std::string& json,
+ std::string* error_response);
+
CONTENT_EXPORT static scoped_refptr<Command> ParseCommand(
const std::string& json,
std::string* error_response);
+ CONTENT_EXPORT static scoped_refptr<Command> ParseCommand(
+ base::DictionaryValue* command_dict,
+ std::string* error_response);
+
CONTENT_EXPORT static scoped_refptr<Command> CreateCommand(
int id,
const std::string& method,
base::DictionaryValue* params);
+ CONTENT_EXPORT static scoped_refptr<Response> ParseResponse(
+ base::DictionaryValue* response_dict);
+
static scoped_refptr<Notification> ParseNotification(
const std::string& json);
static scoped_refptr<Notification> CreateNotification(
const std::string& method, base::DictionaryValue* params);
- private:
- static base::DictionaryValue* ParseMessage(const std::string& json,
- std::string* error_response);
-
DevToolsProtocol() {}
~DevToolsProtocol() {}
};
diff --git a/chromium/content/browser/devtools/devtools_protocol_constants.cc b/chromium/content/browser/devtools/devtools_protocol_constants.cc
deleted file mode 100644
index af5ecd1f580..00000000000
--- a/chromium/content/browser/devtools/devtools_protocol_constants.cc
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// THIS FILE IS AUTOGENERATED.
-// If you need change something in this file, please see
-// protocol.json and browser_protocol.json
-
-#include "content/browser/devtools/devtools_protocol_constants.h"
-
-namespace content {
-namespace devtools {
-
-const char kResult[] = "result";
-
-namespace DOM {
- const char kName[] = "DOM";
-
- namespace Rect {
- const char kParamHeight[] = "height";
- const char kParamWidth[] = "width";
- const char kParamX[] = "x";
- const char kParamY[] = "y";
- } // Rect
-
- namespace setFileInputFiles {
- const char kName[] = "DOM.setFileInputFiles";
- const char kParamFiles[] = "files";
- const char kParamNodeId[] = "nodeId";
- } // setFileInputFiles
-} // DOM
-
-namespace Input {
- const char kName[] = "Input";
-
- namespace dispatchGestureEvent {
- const char kName[] = "Input.dispatchGestureEvent";
- const char kParamDeltaX[] = "deltaX";
- const char kParamDeltaY[] = "deltaY";
- const char kParamPinchScale[] = "pinchScale";
- const char kParamTimestamp[] = "timestamp";
- const char kParamType[] = "type";
- const char kParamX[] = "x";
- const char kParamY[] = "y";
-
- namespace Type {
- const char kEnumPinchBegin[] = "pinchBegin";
- const char kEnumPinchEnd[] = "pinchEnd";
- const char kEnumPinchUpdate[] = "pinchUpdate";
- const char kEnumScrollBegin[] = "scrollBegin";
- const char kEnumScrollEnd[] = "scrollEnd";
- const char kEnumScrollUpdate[] = "scrollUpdate";
- const char kEnumTap[] = "tap";
- const char kEnumTapDown[] = "tapDown";
- } // Type
- } // dispatchGestureEvent
-
- namespace dispatchMouseEvent {
- const char kName[] = "Input.dispatchMouseEvent";
- const char kParamButton[] = "button";
- const char kParamClickCount[] = "clickCount";
- const char kParamDeviceSpace[] = "deviceSpace";
- const char kParamModifiers[] = "modifiers";
- const char kParamTimestamp[] = "timestamp";
- const char kParamType[] = "type";
- const char kParamX[] = "x";
- const char kParamY[] = "y";
-
- namespace Button {
- const char kEnumLeft[] = "left";
- const char kEnumMiddle[] = "middle";
- const char kEnumNone[] = "none";
- const char kEnumRight[] = "right";
- } // Button
-
- namespace Type {
- const char kEnumMouseMoved[] = "mouseMoved";
- const char kEnumMousePressed[] = "mousePressed";
- const char kEnumMouseReleased[] = "mouseReleased";
- } // Type
- } // dispatchMouseEvent
-} // Input
-
-namespace Inspector {
- const char kName[] = "Inspector";
-
- namespace detached {
- const char kName[] = "Inspector.detached";
- const char kParamReason[] = "reason";
- } // detached
-
- namespace targetCrashed {
- const char kName[] = "Inspector.targetCrashed";
- } // targetCrashed
-} // Inspector
-
-namespace Page {
- const char kName[] = "Page";
-
- namespace NavigationEntry {
- const char kParamId[] = "id";
- const char kParamTitle[] = "title";
- const char kParamUrl[] = "url";
- } // NavigationEntry
-
- namespace Quota {
- const char kParamPersistent[] = "persistent";
- const char kParamTemporary[] = "temporary";
- } // Quota
-
- namespace ScreencastFrameMetadata {
- const char kParamDeviceScaleFactor[] = "deviceScaleFactor";
- const char kParamOffsetBottom[] = "offsetBottom";
- const char kParamOffsetTop[] = "offsetTop";
- const char kParamPageScaleFactor[] = "pageScaleFactor";
- const char kParamPageScaleFactorMax[] = "pageScaleFactorMax";
- const char kParamPageScaleFactorMin[] = "pageScaleFactorMin";
- const char kParamViewport[] = "viewport";
- } // ScreencastFrameMetadata
-
- namespace Usage {
- const char kParamPersistent[] = "persistent";
- const char kParamSyncable[] = "syncable";
- const char kParamTemporary[] = "temporary";
- } // Usage
-
- namespace UsageItem {
- const char kParamId[] = "id";
- const char kParamValue[] = "value";
-
- namespace Id {
- const char kEnumAppcache[] = "appcache";
- const char kEnumDatabase[] = "database";
- const char kEnumFilesystem[] = "filesystem";
- const char kEnumIndexeddatabase[] = "indexeddatabase";
- } // Id
- } // UsageItem
-
- namespace canScreencast {
- const char kName[] = "Page.canScreencast";
- const char kResponseResult[] = "result";
- } // canScreencast
-
- namespace captureScreenshot {
- const char kName[] = "Page.captureScreenshot";
- const char kParamFormat[] = "format";
- const char kParamMaxHeight[] = "maxHeight";
- const char kParamMaxWidth[] = "maxWidth";
- const char kParamQuality[] = "quality";
- const char kResponseData[] = "data";
- const char kResponseMetadata[] = "metadata";
-
- namespace Format {
- const char kEnumJpeg[] = "jpeg";
- const char kEnumPng[] = "png";
- } // Format
- } // captureScreenshot
-
- namespace disable {
- const char kName[] = "Page.disable";
- } // disable
-
- namespace getNavigationHistory {
- const char kName[] = "Page.getNavigationHistory";
- const char kResponseCurrentIndex[] = "currentIndex";
- const char kResponseEntries[] = "entries";
- } // getNavigationHistory
-
- namespace handleJavaScriptDialog {
- const char kName[] = "Page.handleJavaScriptDialog";
- const char kParamAccept[] = "accept";
- const char kParamPromptText[] = "promptText";
- } // handleJavaScriptDialog
-
- namespace navigate {
- const char kName[] = "Page.navigate";
- const char kParamUrl[] = "url";
- } // navigate
-
- namespace navigateToHistoryEntry {
- const char kName[] = "Page.navigateToHistoryEntry";
- const char kParamEntryId[] = "entryId";
- } // navigateToHistoryEntry
-
- namespace queryUsageAndQuota {
- const char kName[] = "Page.queryUsageAndQuota";
- const char kParamSecurityOrigin[] = "securityOrigin";
- const char kResponseQuota[] = "quota";
- const char kResponseUsage[] = "usage";
- } // queryUsageAndQuota
-
- namespace reload {
- const char kName[] = "Page.reload";
- const char kParamIgnoreCache[] = "ignoreCache";
- const char kParamScriptPreprocessor[] = "scriptPreprocessor";
- const char kParamScriptToEvaluateOnLoad[] = "scriptToEvaluateOnLoad";
- } // reload
-
- namespace screencastFrame {
- const char kName[] = "Page.screencastFrame";
- const char kParamData[] = "data";
- const char kParamMetadata[] = "metadata";
- } // screencastFrame
-
- namespace screencastVisibilityChanged {
- const char kName[] = "Page.screencastVisibilityChanged";
- const char kParamVisible[] = "visible";
- } // screencastVisibilityChanged
-
- namespace startScreencast {
- const char kName[] = "Page.startScreencast";
- const char kParamFormat[] = "format";
- const char kParamMaxHeight[] = "maxHeight";
- const char kParamMaxWidth[] = "maxWidth";
- const char kParamQuality[] = "quality";
-
- namespace Format {
- const char kEnumJpeg[] = "jpeg";
- const char kEnumPng[] = "png";
- } // Format
- } // startScreencast
-
- namespace stopScreencast {
- const char kName[] = "Page.stopScreencast";
- } // stopScreencast
-} // Page
-
-namespace SystemInfo {
- const char kName[] = "SystemInfo";
-
- namespace GPUDevice {
- const char kParamDeviceId[] = "deviceId";
- const char kParamDeviceString[] = "deviceString";
- const char kParamVendorId[] = "vendorId";
- const char kParamVendorString[] = "vendorString";
- } // GPUDevice
-
- namespace GPUInfo {
- const char kParamAuxAttributes[] = "auxAttributes";
- const char kParamDevices[] = "devices";
- const char kParamFeatureStatus[] = "featureStatus";
- } // GPUInfo
-
- namespace SystemInfo {
- const char kParamGpu[] = "gpu";
- const char kParamModelName[] = "modelName";
- } // SystemInfo
-
- namespace getInfo {
- const char kName[] = "SystemInfo.getInfo";
- const char kResponseInfo[] = "info";
- } // getInfo
-} // SystemInfo
-
-namespace Tracing {
- const char kName[] = "Tracing";
-
- namespace dataCollected {
- const char kName[] = "Tracing.dataCollected";
- const char kParamValue[] = "value";
- } // dataCollected
-
- namespace end {
- const char kName[] = "Tracing.end";
- } // end
-
- namespace start {
- const char kName[] = "Tracing.start";
- const char kParamCategories[] = "categories";
- const char kParamOptions[] = "options";
- } // start
-
- namespace tracingComplete {
- const char kName[] = "Tracing.tracingComplete";
- } // tracingComplete
-} // Tracing
-
-namespace Worker {
- const char kName[] = "Worker";
-
- namespace disconnectFromWorker {
- const char kName[] = "Worker.disconnectFromWorker";
- const char kParamWorkerId[] = "workerId";
- } // disconnectFromWorker
-
- namespace disconnectedFromWorker {
- const char kName[] = "Worker.disconnectedFromWorker";
- } // disconnectedFromWorker
-} // Worker
-
-
-} // devtools
-} // content
diff --git a/chromium/content/browser/devtools/devtools_protocol_constants.h b/chromium/content/browser/devtools/devtools_protocol_constants.h
deleted file mode 100644
index 8ed159bc0df..00000000000
--- a/chromium/content/browser/devtools/devtools_protocol_constants.h
+++ /dev/null
@@ -1,296 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_CONSTANTSH_
-#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_CONSTANTSH_
-
-// THIS FILE IS AUTOGENERATED.
-// If you need change something in this file, please see
-// protocol.json and browser_protocol.json
-
-namespace content {
-namespace devtools {
-
-extern const char kResult[];
-
-namespace DOM {
- extern const char kName[];
-
- namespace Rect {
- extern const char kParamHeight[];
- extern const char kParamWidth[];
- extern const char kParamX[];
- extern const char kParamY[];
- } // Rect
-
- namespace setFileInputFiles {
- extern const char kName[];
- extern const char kParamFiles[];
- extern const char kParamNodeId[];
- } // setFileInputFiles
-} // DOM
-
-namespace Input {
- extern const char kName[];
-
- namespace dispatchGestureEvent {
- extern const char kName[];
- extern const char kParamDeltaX[];
- extern const char kParamDeltaY[];
- extern const char kParamPinchScale[];
- extern const char kParamTimestamp[];
- extern const char kParamType[];
- extern const char kParamX[];
- extern const char kParamY[];
-
- namespace Type {
- extern const char kEnumPinchBegin[];
- extern const char kEnumPinchEnd[];
- extern const char kEnumPinchUpdate[];
- extern const char kEnumScrollBegin[];
- extern const char kEnumScrollEnd[];
- extern const char kEnumScrollUpdate[];
- extern const char kEnumTap[];
- extern const char kEnumTapDown[];
- } // Type
- } // dispatchGestureEvent
-
- namespace dispatchMouseEvent {
- extern const char kName[];
- extern const char kParamButton[];
- extern const char kParamClickCount[];
- extern const char kParamDeviceSpace[];
- extern const char kParamModifiers[];
- extern const char kParamTimestamp[];
- extern const char kParamType[];
- extern const char kParamX[];
- extern const char kParamY[];
-
- namespace Button {
- extern const char kEnumLeft[];
- extern const char kEnumMiddle[];
- extern const char kEnumNone[];
- extern const char kEnumRight[];
- } // Button
-
- namespace Type {
- extern const char kEnumMouseMoved[];
- extern const char kEnumMousePressed[];
- extern const char kEnumMouseReleased[];
- } // Type
- } // dispatchMouseEvent
-} // Input
-
-namespace Inspector {
- extern const char kName[];
-
- namespace detached {
- extern const char kName[];
- extern const char kParamReason[];
- } // detached
-
- namespace targetCrashed {
- extern const char kName[];
- } // targetCrashed
-} // Inspector
-
-namespace Page {
- extern const char kName[];
-
- namespace NavigationEntry {
- extern const char kParamId[];
- extern const char kParamTitle[];
- extern const char kParamUrl[];
- } // NavigationEntry
-
- namespace Quota {
- extern const char kParamPersistent[];
- extern const char kParamTemporary[];
- } // Quota
-
- namespace ScreencastFrameMetadata {
- extern const char kParamDeviceScaleFactor[];
- extern const char kParamOffsetBottom[];
- extern const char kParamOffsetTop[];
- extern const char kParamPageScaleFactor[];
- extern const char kParamPageScaleFactorMax[];
- extern const char kParamPageScaleFactorMin[];
- extern const char kParamViewport[];
- } // ScreencastFrameMetadata
-
- namespace Usage {
- extern const char kParamPersistent[];
- extern const char kParamSyncable[];
- extern const char kParamTemporary[];
- } // Usage
-
- namespace UsageItem {
- extern const char kParamId[];
- extern const char kParamValue[];
-
- namespace Id {
- extern const char kEnumAppcache[];
- extern const char kEnumDatabase[];
- extern const char kEnumFilesystem[];
- extern const char kEnumIndexeddatabase[];
- } // Id
- } // UsageItem
-
- namespace canScreencast {
- extern const char kName[];
- extern const char kResponseResult[];
- } // canScreencast
-
- namespace captureScreenshot {
- extern const char kName[];
- extern const char kParamFormat[];
- extern const char kParamMaxHeight[];
- extern const char kParamMaxWidth[];
- extern const char kParamQuality[];
- extern const char kResponseData[];
- extern const char kResponseMetadata[];
-
- namespace Format {
- extern const char kEnumJpeg[];
- extern const char kEnumPng[];
- } // Format
- } // captureScreenshot
-
- namespace disable {
- extern const char kName[];
- } // disable
-
- namespace getNavigationHistory {
- extern const char kName[];
- extern const char kResponseCurrentIndex[];
- extern const char kResponseEntries[];
- } // getNavigationHistory
-
- namespace handleJavaScriptDialog {
- extern const char kName[];
- extern const char kParamAccept[];
- extern const char kParamPromptText[];
- } // handleJavaScriptDialog
-
- namespace navigate {
- extern const char kName[];
- extern const char kParamUrl[];
- } // navigate
-
- namespace navigateToHistoryEntry {
- extern const char kName[];
- extern const char kParamEntryId[];
- } // navigateToHistoryEntry
-
- namespace queryUsageAndQuota {
- extern const char kName[];
- extern const char kParamSecurityOrigin[];
- extern const char kResponseQuota[];
- extern const char kResponseUsage[];
- } // queryUsageAndQuota
-
- namespace reload {
- extern const char kName[];
- extern const char kParamIgnoreCache[];
- extern const char kParamScriptPreprocessor[];
- extern const char kParamScriptToEvaluateOnLoad[];
- } // reload
-
- namespace screencastFrame {
- extern const char kName[];
- extern const char kParamData[];
- extern const char kParamMetadata[];
- } // screencastFrame
-
- namespace screencastVisibilityChanged {
- extern const char kName[];
- extern const char kParamVisible[];
- } // screencastVisibilityChanged
-
- namespace startScreencast {
- extern const char kName[];
- extern const char kParamFormat[];
- extern const char kParamMaxHeight[];
- extern const char kParamMaxWidth[];
- extern const char kParamQuality[];
-
- namespace Format {
- extern const char kEnumJpeg[];
- extern const char kEnumPng[];
- } // Format
- } // startScreencast
-
- namespace stopScreencast {
- extern const char kName[];
- } // stopScreencast
-} // Page
-
-namespace SystemInfo {
- extern const char kName[];
-
- namespace GPUDevice {
- extern const char kParamDeviceId[];
- extern const char kParamDeviceString[];
- extern const char kParamVendorId[];
- extern const char kParamVendorString[];
- } // GPUDevice
-
- namespace GPUInfo {
- extern const char kParamAuxAttributes[];
- extern const char kParamDevices[];
- extern const char kParamFeatureStatus[];
- } // GPUInfo
-
- namespace SystemInfo {
- extern const char kParamGpu[];
- extern const char kParamModelName[];
- } // SystemInfo
-
- namespace getInfo {
- extern const char kName[];
- extern const char kResponseInfo[];
- } // getInfo
-} // SystemInfo
-
-namespace Tracing {
- extern const char kName[];
-
- namespace dataCollected {
- extern const char kName[];
- extern const char kParamValue[];
- } // dataCollected
-
- namespace end {
- extern const char kName[];
- } // end
-
- namespace start {
- extern const char kName[];
- extern const char kParamCategories[];
- extern const char kParamOptions[];
- } // start
-
- namespace tracingComplete {
- extern const char kName[];
- } // tracingComplete
-} // Tracing
-
-namespace Worker {
- extern const char kName[];
-
- namespace disconnectFromWorker {
- extern const char kName[];
- extern const char kParamWorkerId[];
- } // disconnectFromWorker
-
- namespace disconnectedFromWorker {
- extern const char kName[];
- } // disconnectedFromWorker
-} // Worker
-
-
-} // devtools
-} // content
-
-#endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_CONSTANTSH_
diff --git a/chromium/content/browser/devtools/devtools_resources.gyp b/chromium/content/browser/devtools/devtools_resources.gyp
index 30b42209453..72ae7060549 100644
--- a/chromium/content/browser/devtools/devtools_resources.gyp
+++ b/chromium/content/browser/devtools/devtools_resources.gyp
@@ -22,6 +22,7 @@
'variables': {
'grit_cmd': ['python', '../../../tools/grit/grit.py'],
'grit_grd_file': '<(SHARED_INTERMEDIATE_DIR)/devtools/devtools_resources.grd',
+ 'grit_rc_header_format%': '',
},
'inputs': [
'<(grit_grd_file)',
@@ -35,14 +36,47 @@
],
'action': ['<@(grit_cmd)',
'-i', '<(grit_grd_file)', 'build',
- '-f', 'GRIT_DIR/../gritsettings/resource_ids',
+ '-f', '<(DEPTH)/tools/gritsettings/resource_ids',
'-o', '<(grit_out_dir)',
'-D', 'SHARED_INTERMEDIATE_DIR=<(SHARED_INTERMEDIATE_DIR)',
- '<@(grit_defines)' ],
+ '<@(grit_defines)',
+ '<@(grit_rc_header_format)'],
'message': 'Generating resources from <(grit_grd_file)',
- 'msvs_cygwin_shell': 1,
+ },
+ {
+ 'action_name': 'devtools_protocol_constants',
+ 'variables': {
+ 'blink_protocol': '../../../third_party/WebKit/Source/devtools/protocol.json',
+ 'browser_protocol': 'browser_protocol.json',
+ 'generator': '../../public/browser/devtools_protocol_constants_generator.py',
+ 'package': 'content'
+ },
+ 'inputs': [
+ '<(blink_protocol)',
+ '<(browser_protocol)',
+ '<(generator)',
+ ],
+ 'outputs': [
+ '<(SHARED_INTERMEDIATE_DIR)/<(package)/browser/devtools/devtools_protocol_constants.cc',
+ '<(SHARED_INTERMEDIATE_DIR)/<(package)/browser/devtools/devtools_protocol_constants.h'
+ ],
+ 'action':[
+ 'python',
+ '<(generator)',
+ '<(package)',
+ '<(SHARED_INTERMEDIATE_DIR)/<(package)/browser/devtools/devtools_protocol_constants.cc',
+ '<(SHARED_INTERMEDIATE_DIR)/<(package)/browser/devtools/devtools_protocol_constants.h',
+ '<(blink_protocol)',
+ '<(browser_protocol)',
+ ],
+ 'message': 'Generating DevTools protocol constants from <(blink_protocol)'
}
],
+ 'direct_dependent_settings': {
+ 'include_dirs': [
+ '<(SHARED_INTERMEDIATE_DIR)',
+ ]
+ },
'includes': [ '../../../build/grit_target.gypi' ],
},
],
diff --git a/chromium/content/browser/devtools/devtools_system_info_handler.cc b/chromium/content/browser/devtools/devtools_system_info_handler.cc
index 4ade158c2bc..6e0336d2c08 100644
--- a/chromium/content/browser/devtools/devtools_system_info_handler.cc
+++ b/chromium/content/browser/devtools/devtools_system_info_handler.cc
@@ -20,9 +20,11 @@ const char kAuxAttributes[] = "auxAttributes";
const char kDeviceId[] = "deviceId";
const char kDeviceString[] = "deviceString";
const char kDevices[] = "devices";
+const char kDriverBugWorkarounds[] = "driverBugWorkarounds";
const char kFeatureStatus[] = "featureStatus";
const char kGPU[] = "gpu";
const char kModelName[] = "modelName";
+const char kModelVersion[] = "modelVersion";
const char kVendorId[] = "vendorId";
const char kVendorString[] = "vendorString";
@@ -118,8 +120,11 @@ DevToolsSystemInfoHandler::OnGetInfo(
gpu_dict->Set(kFeatureStatus, GetFeatureStatus());
+ gpu_dict->Set(kDriverBugWorkarounds, GetDriverBugWorkarounds());
+
base::DictionaryValue* system_dict = new base::DictionaryValue;
- system_dict->SetString(kModelName, gpu_info.machine_model);
+ system_dict->SetString(kModelName, gpu_info.machine_model_name);
+ system_dict->SetString(kModelVersion, gpu_info.machine_model_version);
system_dict->Set(kGPU, gpu_dict);
return command->SuccessResponse(system_dict);
}
diff --git a/chromium/content/browser/devtools/devtools_tracing_handler.cc b/chromium/content/browser/devtools/devtools_tracing_handler.cc
index e9f6cf10b29..7d308642212 100644
--- a/chromium/content/browser/devtools/devtools_tracing_handler.cc
+++ b/chromium/content/browser/devtools/devtools_tracing_handler.cc
@@ -4,6 +4,8 @@
#include "content/browser/devtools/devtools_tracing_handler.h"
+#include <cmath>
+
#include "base/bind.h"
#include "base/callback.h"
#include "base/file_util.h"
@@ -13,6 +15,8 @@
#include "base/memory/ref_counted_memory.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
#include "base/values.h"
#include "content/browser/devtools/devtools_http_handler_impl.h"
#include "content/browser/devtools/devtools_protocol_constants.h"
@@ -42,14 +46,18 @@ void ReadFile(
} // namespace
-DevToolsTracingHandler::DevToolsTracingHandler()
- : weak_factory_(this) {
+DevToolsTracingHandler::DevToolsTracingHandler(
+ DevToolsTracingHandler::Target target)
+ : weak_factory_(this), target_(target) {
RegisterCommandHandler(devtools::Tracing::start::kName,
base::Bind(&DevToolsTracingHandler::OnStart,
base::Unretained(this)));
RegisterCommandHandler(devtools::Tracing::end::kName,
base::Bind(&DevToolsTracingHandler::OnEnd,
base::Unretained(this)));
+ RegisterCommandHandler(devtools::Tracing::getCategories::kName,
+ base::Bind(&DevToolsTracingHandler::OnGetCategories,
+ base::Unretained(this)));
}
DevToolsTracingHandler::~DevToolsTracingHandler() {
@@ -69,10 +77,10 @@ void DevToolsTracingHandler::ReadRecordingResult(
if (trace_data->data().size()) {
scoped_ptr<base::Value> trace_value(base::JSONReader::Read(
trace_data->data()));
- DictionaryValue* dictionary = NULL;
+ base::DictionaryValue* dictionary = NULL;
bool ok = trace_value->GetAsDictionary(&dictionary);
DCHECK(ok);
- ListValue* list = NULL;
+ base::ListValue* list = NULL;
ok = dictionary->GetList("traceEvents", &list);
DCHECK(ok);
std::string buffer;
@@ -142,20 +150,99 @@ DevToolsTracingHandler::OnStart(
options = TraceOptionsFromString(options_param);
}
+ if (params && params->HasKey(
+ devtools::Tracing::start::kParamBufferUsageReportingInterval)) {
+ double usage_reporting_interval = 0.0;
+ params->GetDouble(
+ devtools::Tracing::start::kParamBufferUsageReportingInterval,
+ &usage_reporting_interval);
+ if (usage_reporting_interval > 0) {
+ base::TimeDelta interval = base::TimeDelta::FromMilliseconds(
+ std::ceil(usage_reporting_interval));
+ buffer_usage_poll_timer_.reset(new base::Timer(
+ FROM_HERE,
+ interval,
+ base::Bind(
+ base::IgnoreResult(&TracingController::GetTraceBufferPercentFull),
+ base::Unretained(TracingController::GetInstance()),
+ base::Bind(&DevToolsTracingHandler::OnBufferUsage,
+ weak_factory_.GetWeakPtr())),
+ true));
+ buffer_usage_poll_timer_->Reset();
+ }
+ }
+
+ // If inspected target is a render process Tracing.start will be handled by
+ // tracing agent in the renderer.
+ if (target_ == Renderer) {
+ TracingController::GetInstance()->EnableRecording(
+ categories, options, TracingController::EnableRecordingDoneCallback());
+ return NULL;
+ }
+
TracingController::GetInstance()->EnableRecording(
categories, options,
- TracingController::EnableRecordingDoneCallback());
- return command->SuccessResponse(NULL);
+ base::Bind(&DevToolsTracingHandler::OnTracingStarted,
+ weak_factory_.GetWeakPtr(),
+ command));
+
+ return command->AsyncResponsePromise();
+}
+
+void DevToolsTracingHandler::OnTracingStarted(
+ scoped_refptr<DevToolsProtocol::Command> command) {
+ SendAsyncResponse(command->SuccessResponse(NULL));
+}
+
+void DevToolsTracingHandler::OnBufferUsage(float usage) {
+ base::DictionaryValue* params = new base::DictionaryValue();
+ params->SetDouble(devtools::Tracing::bufferUsage::kParamValue, usage);
+ SendNotification(devtools::Tracing::bufferUsage::kName, params);
}
scoped_refptr<DevToolsProtocol::Response>
DevToolsTracingHandler::OnEnd(
scoped_refptr<DevToolsProtocol::Command> command) {
- TracingController::GetInstance()->DisableRecording(
- base::FilePath(),
+ DisableRecording(
base::Bind(&DevToolsTracingHandler::BeginReadingRecordingResult,
weak_factory_.GetWeakPtr()));
return command->SuccessResponse(NULL);
}
+void DevToolsTracingHandler::DisableRecording(
+ const TracingController::TracingFileResultCallback& callback) {
+ buffer_usage_poll_timer_.reset();
+ TracingController::GetInstance()->DisableRecording(base::FilePath(),
+ callback);
+}
+
+void DevToolsTracingHandler::OnClientDetached() {
+ DisableRecording();
+}
+
+scoped_refptr<DevToolsProtocol::Response>
+DevToolsTracingHandler::OnGetCategories(
+ scoped_refptr<DevToolsProtocol::Command> command) {
+ TracingController::GetInstance()->GetCategories(
+ base::Bind(&DevToolsTracingHandler::OnCategoriesReceived,
+ weak_factory_.GetWeakPtr(),
+ command));
+ return command->AsyncResponsePromise();
+}
+
+void DevToolsTracingHandler::OnCategoriesReceived(
+ scoped_refptr<DevToolsProtocol::Command> command,
+ const std::set<std::string>& category_set) {
+ base::DictionaryValue* response = new base::DictionaryValue;
+ base::ListValue* category_list = new base::ListValue;
+ for (std::set<std::string>::const_iterator it = category_set.begin();
+ it != category_set.end(); ++it) {
+ category_list->AppendString(*it);
+ }
+
+ response->Set(devtools::Tracing::getCategories::kResponseCategories,
+ category_list);
+ SendAsyncResponse(command->SuccessResponse(response));
+}
+
} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_tracing_handler.h b/chromium/content/browser/devtools/devtools_tracing_handler.h
index b551e7579e2..7c3b8e645e4 100644
--- a/chromium/content/browser/devtools/devtools_tracing_handler.h
+++ b/chromium/content/browser/devtools/devtools_tracing_handler.h
@@ -5,12 +5,16 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TRACING_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_TRACING_HANDLER_H_
+#include <set>
+#include <string>
+
#include "base/memory/weak_ptr.h"
#include "content/browser/devtools/devtools_protocol.h"
#include "content/public/browser/tracing_controller.h"
namespace base {
class RefCountedString;
+class Timer;
}
namespace content {
@@ -19,23 +23,38 @@ namespace content {
// infrastructure.
class DevToolsTracingHandler : public DevToolsProtocol::Handler {
public:
- DevToolsTracingHandler();
+ enum Target { Browser, Renderer };
+ explicit DevToolsTracingHandler(Target target);
virtual ~DevToolsTracingHandler();
+ void OnClientDetached();
+
private:
void BeginReadingRecordingResult(const base::FilePath& path);
void ReadRecordingResult(const scoped_refptr<base::RefCountedString>& result);
void OnTraceDataCollected(const std::string& trace_fragment);
+ void OnTracingStarted(scoped_refptr<DevToolsProtocol::Command> command);
+ void OnBufferUsage(float usage);
scoped_refptr<DevToolsProtocol::Response> OnStart(
scoped_refptr<DevToolsProtocol::Command> command);
scoped_refptr<DevToolsProtocol::Response> OnEnd(
scoped_refptr<DevToolsProtocol::Command> command);
+ scoped_refptr<DevToolsProtocol::Response> OnGetCategories(
+ scoped_refptr<DevToolsProtocol::Command> command);
+ void OnCategoriesReceived(scoped_refptr<DevToolsProtocol::Command> command,
+ const std::set<std::string>& category_set);
+
TracingController::Options TraceOptionsFromString(const std::string& options);
- base::WeakPtrFactory<DevToolsTracingHandler> weak_factory_;
+ void DisableRecording(
+ const TracingController::TracingFileResultCallback& callback =
+ TracingController::TracingFileResultCallback());
+ base::WeakPtrFactory<DevToolsTracingHandler> weak_factory_;
+ scoped_ptr<base::Timer> buffer_usage_poll_timer_;
+ Target target_;
DISALLOW_COPY_AND_ASSIGN(DevToolsTracingHandler);
};
diff --git a/chromium/content/browser/devtools/embedded_worker_devtools_manager.cc b/chromium/content/browser/devtools/embedded_worker_devtools_manager.cc
new file mode 100644
index 00000000000..3ba61aafeea
--- /dev/null
+++ b/chromium/content/browser/devtools/embedded_worker_devtools_manager.cc
@@ -0,0 +1,379 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/devtools/embedded_worker_devtools_manager.h"
+
+#include "content/browser/devtools/devtools_manager_impl.h"
+#include "content/browser/devtools/devtools_protocol.h"
+#include "content/browser/devtools/devtools_protocol_constants.h"
+#include "content/browser/devtools/ipc_devtools_agent_host.h"
+#include "content/browser/shared_worker/shared_worker_instance.h"
+#include "content/common/devtools_messages.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/worker_service.h"
+#include "ipc/ipc_listener.h"
+
+namespace content {
+
+namespace {
+
+bool SendMessageToWorker(
+ const EmbeddedWorkerDevToolsManager::WorkerId& worker_id,
+ IPC::Message* message) {
+ RenderProcessHost* host = RenderProcessHost::FromID(worker_id.first);
+ if (!host) {
+ delete message;
+ return false;
+ }
+ message->set_routing_id(worker_id.second);
+ host->Send(message);
+ return true;
+}
+
+} // namespace
+
+EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::ServiceWorkerIdentifier(
+ const ServiceWorkerContextCore* const service_worker_context,
+ int64 service_worker_version_id)
+ : service_worker_context_(service_worker_context),
+ service_worker_version_id_(service_worker_version_id) {
+}
+
+EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::ServiceWorkerIdentifier(
+ const ServiceWorkerIdentifier& other)
+ : service_worker_context_(other.service_worker_context_),
+ service_worker_version_id_(other.service_worker_version_id_) {
+}
+
+bool EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::Matches(
+ const ServiceWorkerIdentifier& other) const {
+ return service_worker_context_ == other.service_worker_context_ &&
+ service_worker_version_id_ == other.service_worker_version_id_;
+}
+
+EmbeddedWorkerDevToolsManager::WorkerInfo::WorkerInfo(
+ const SharedWorkerInstance& instance)
+ : shared_worker_instance_(new SharedWorkerInstance(instance)),
+ state_(WORKER_UNINSPECTED),
+ agent_host_(NULL) {
+}
+
+EmbeddedWorkerDevToolsManager::WorkerInfo::WorkerInfo(
+ const ServiceWorkerIdentifier& service_worker_id)
+ : service_worker_id_(new ServiceWorkerIdentifier(service_worker_id)),
+ state_(WORKER_UNINSPECTED),
+ agent_host_(NULL) {
+}
+
+bool EmbeddedWorkerDevToolsManager::WorkerInfo::Matches(
+ const SharedWorkerInstance& other) {
+ if (!shared_worker_instance_)
+ return false;
+ return shared_worker_instance_->Matches(other);
+}
+
+bool EmbeddedWorkerDevToolsManager::WorkerInfo::Matches(
+ const ServiceWorkerIdentifier& other) {
+ if (!service_worker_id_)
+ return false;
+ return service_worker_id_->Matches(other);
+}
+
+EmbeddedWorkerDevToolsManager::WorkerInfo::~WorkerInfo() {
+}
+
+class EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsAgentHost
+ : public IPCDevToolsAgentHost,
+ public IPC::Listener {
+ public:
+ explicit EmbeddedWorkerDevToolsAgentHost(WorkerId worker_id)
+ : worker_id_(worker_id), worker_attached_(false) {
+ AttachToWorker();
+ }
+
+ // DevToolsAgentHost override.
+ virtual bool IsWorker() const OVERRIDE { return true; }
+
+ // IPCDevToolsAgentHost implementation.
+ virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE {
+ if (worker_attached_)
+ SendMessageToWorker(worker_id_, message);
+ else
+ delete message;
+ }
+ virtual void Attach() OVERRIDE {
+ AttachToWorker();
+ IPCDevToolsAgentHost::Attach();
+ }
+ virtual void OnClientAttached() OVERRIDE {}
+ virtual void OnClientDetached() OVERRIDE { DetachFromWorker(); }
+
+ // IPC::Listener implementation.
+ virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(EmbeddedWorkerDevToolsAgentHost, msg)
+ IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend,
+ OnDispatchOnInspectorFrontend)
+ IPC_MESSAGE_HANDLER(DevToolsHostMsg_SaveAgentRuntimeState,
+ OnSaveAgentRuntimeState)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+ }
+
+ void ReattachToWorker(WorkerId worker_id) {
+ CHECK(!worker_attached_);
+ worker_id_ = worker_id;
+ if (!IsAttached())
+ return;
+ AttachToWorker();
+ Reattach(state_);
+ }
+
+ void DetachFromWorker() {
+ if (!worker_attached_)
+ return;
+ worker_attached_ = false;
+ if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
+ host->RemoveRoute(worker_id_.second);
+ Release();
+ }
+
+ WorkerId worker_id() const { return worker_id_; }
+
+ private:
+ virtual ~EmbeddedWorkerDevToolsAgentHost() {
+ CHECK(!worker_attached_);
+ EmbeddedWorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(
+ this);
+ }
+
+ void OnDispatchOnInspectorFrontend(const std::string& message) {
+ DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(this,
+ message);
+ }
+
+ void OnSaveAgentRuntimeState(const std::string& state) { state_ = state; }
+
+ void AttachToWorker() {
+ if (worker_attached_)
+ return;
+ worker_attached_ = true;
+ AddRef();
+ if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
+ host->AddRoute(worker_id_.second, this);
+ }
+
+ WorkerId worker_id_;
+ bool worker_attached_;
+ std::string state_;
+ DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerDevToolsAgentHost);
+};
+
+// static
+EmbeddedWorkerDevToolsManager* EmbeddedWorkerDevToolsManager::GetInstance() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ return Singleton<EmbeddedWorkerDevToolsManager>::get();
+}
+
+DevToolsAgentHost* EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForWorker(
+ int worker_process_id,
+ int worker_route_id) {
+ WorkerId id(worker_process_id, worker_route_id);
+
+ WorkerInfoMap::iterator it = workers_.find(id);
+ if (it == workers_.end())
+ return NULL;
+
+ WorkerInfo* info = it->second;
+ if (info->state() != WORKER_UNINSPECTED &&
+ info->state() != WORKER_PAUSED_FOR_DEBUG_ON_START) {
+ return info->agent_host();
+ }
+
+ EmbeddedWorkerDevToolsAgentHost* agent_host =
+ new EmbeddedWorkerDevToolsAgentHost(id);
+ info->set_agent_host(agent_host);
+ info->set_state(WORKER_INSPECTED);
+ return agent_host;
+}
+
+DevToolsAgentHost*
+EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForServiceWorker(
+ const ServiceWorkerIdentifier& service_worker_id) {
+ WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(service_worker_id);
+ if (it == workers_.end())
+ return NULL;
+ return GetDevToolsAgentHostForWorker(it->first.first, it->first.second);
+}
+
+EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsManager()
+ : debug_service_worker_on_start_(false) {
+}
+
+EmbeddedWorkerDevToolsManager::~EmbeddedWorkerDevToolsManager() {
+}
+
+bool EmbeddedWorkerDevToolsManager::SharedWorkerCreated(
+ int worker_process_id,
+ int worker_route_id,
+ const SharedWorkerInstance& instance) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ const WorkerId id(worker_process_id, worker_route_id);
+ WorkerInfoMap::iterator it = FindExistingSharedWorkerInfo(instance);
+ if (it == workers_.end()) {
+ scoped_ptr<WorkerInfo> info(new WorkerInfo(instance));
+ workers_.set(id, info.Pass());
+ return false;
+ }
+ MoveToPausedState(id, it);
+ return true;
+}
+
+bool EmbeddedWorkerDevToolsManager::ServiceWorkerCreated(
+ int worker_process_id,
+ int worker_route_id,
+ const ServiceWorkerIdentifier& service_worker_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ const WorkerId id(worker_process_id, worker_route_id);
+ WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(service_worker_id);
+ if (it == workers_.end()) {
+ scoped_ptr<WorkerInfo> info(new WorkerInfo(service_worker_id));
+ if (debug_service_worker_on_start_)
+ info->set_state(WORKER_PAUSED_FOR_DEBUG_ON_START);
+ workers_.set(id, info.Pass());
+ return debug_service_worker_on_start_;
+ }
+ MoveToPausedState(id, it);
+ return true;
+}
+
+void EmbeddedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id,
+ int worker_route_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ const WorkerId id(worker_process_id, worker_route_id);
+ WorkerInfoMap::iterator it = workers_.find(id);
+ DCHECK(it != workers_.end());
+ WorkerInfo* info = it->second;
+ switch (info->state()) {
+ case WORKER_UNINSPECTED:
+ case WORKER_PAUSED_FOR_DEBUG_ON_START:
+ workers_.erase(it);
+ break;
+ case WORKER_INSPECTED: {
+ EmbeddedWorkerDevToolsAgentHost* agent_host = info->agent_host();
+ info->set_state(WORKER_TERMINATED);
+ if (!agent_host->IsAttached()) {
+ agent_host->DetachFromWorker();
+ return;
+ }
+ // Client host is debugging this worker agent host.
+ std::string notification =
+ DevToolsProtocol::CreateNotification(
+ devtools::Worker::disconnectedFromWorker::kName, NULL)
+ ->Serialize();
+ DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(
+ agent_host, notification);
+ agent_host->DetachFromWorker();
+ break;
+ }
+ case WORKER_TERMINATED:
+ NOTREACHED();
+ break;
+ case WORKER_PAUSED_FOR_REATTACH: {
+ scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(it);
+ worker_info->set_state(WORKER_TERMINATED);
+ const WorkerId old_id = worker_info->agent_host()->worker_id();
+ workers_.set(old_id, worker_info.Pass());
+ break;
+ }
+ }
+}
+
+void EmbeddedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id,
+ int worker_route_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ const WorkerId id(worker_process_id, worker_route_id);
+ WorkerInfoMap::iterator it = workers_.find(id);
+ DCHECK(it != workers_.end());
+ WorkerInfo* info = it->second;
+ if (info->state() == WORKER_PAUSED_FOR_DEBUG_ON_START) {
+ RenderProcessHost* rph = RenderProcessHost::FromID(worker_process_id);
+ scoped_refptr<DevToolsAgentHost> agent_host(
+ GetDevToolsAgentHostForWorker(worker_process_id, worker_route_id));
+ DevToolsManagerImpl::GetInstance()->Inspect(rph->GetBrowserContext(),
+ agent_host.get());
+ } else if (info->state() == WORKER_PAUSED_FOR_REATTACH) {
+ info->agent_host()->ReattachToWorker(id);
+ info->set_state(WORKER_INSPECTED);
+ }
+}
+
+void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData(
+ EmbeddedWorkerDevToolsAgentHost* agent_host) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ const WorkerId id(agent_host->worker_id());
+ scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(id);
+ if (worker_info) {
+ DCHECK_EQ(worker_info->agent_host(), agent_host);
+ if (worker_info->state() == WORKER_TERMINATED)
+ return;
+ DCHECK_EQ(worker_info->state(), WORKER_INSPECTED);
+ worker_info->set_agent_host(NULL);
+ worker_info->set_state(WORKER_UNINSPECTED);
+ workers_.set(id, worker_info.Pass());
+ return;
+ }
+ for (WorkerInfoMap::iterator it = workers_.begin(); it != workers_.end();
+ ++it) {
+ if (it->second->agent_host() == agent_host) {
+ DCHECK_EQ(WORKER_PAUSED_FOR_REATTACH, it->second->state());
+ SendMessageToWorker(
+ it->first,
+ new DevToolsAgentMsg_ResumeWorkerContext(it->first.second));
+ it->second->set_agent_host(NULL);
+ it->second->set_state(WORKER_UNINSPECTED);
+ return;
+ }
+ }
+}
+
+EmbeddedWorkerDevToolsManager::WorkerInfoMap::iterator
+EmbeddedWorkerDevToolsManager::FindExistingSharedWorkerInfo(
+ const SharedWorkerInstance& instance) {
+ WorkerInfoMap::iterator it = workers_.begin();
+ for (; it != workers_.end(); ++it) {
+ if (it->second->Matches(instance))
+ break;
+ }
+ return it;
+}
+
+EmbeddedWorkerDevToolsManager::WorkerInfoMap::iterator
+EmbeddedWorkerDevToolsManager::FindExistingServiceWorkerInfo(
+ const ServiceWorkerIdentifier& service_worker_id) {
+ WorkerInfoMap::iterator it = workers_.begin();
+ for (; it != workers_.end(); ++it) {
+ if (it->second->Matches(service_worker_id))
+ break;
+ }
+ return it;
+}
+
+void EmbeddedWorkerDevToolsManager::MoveToPausedState(
+ const WorkerId& id,
+ const WorkerInfoMap::iterator& it) {
+ DCHECK_EQ(WORKER_TERMINATED, it->second->state());
+ scoped_ptr<WorkerInfo> info = workers_.take_and_erase(it);
+ info->set_state(WORKER_PAUSED_FOR_REATTACH);
+ workers_.set(id, info.Pass());
+}
+
+void EmbeddedWorkerDevToolsManager::ResetForTesting() {
+ workers_.clear();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/devtools/embedded_worker_devtools_manager.h b/chromium/content/browser/devtools/embedded_worker_devtools_manager.h
new file mode 100644
index 00000000000..3b15c8f2099
--- /dev/null
+++ b/chromium/content/browser/devtools/embedded_worker_devtools_manager.h
@@ -0,0 +1,138 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DEVTOOLS_EMBEDDED_WORKER_DEVTOOLS_MANAGER_H_
+#define CONTENT_BROWSER_DEVTOOLS_EMBEDDED_WORKER_DEVTOOLS_MANAGER_H_
+
+#include "base/basictypes.h"
+#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_vector.h"
+#include "base/memory/singleton.h"
+#include "base/strings/string16.h"
+#include "content/browser/shared_worker/shared_worker_instance.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class DevToolsAgentHost;
+class ServiceWorkerContextCore;
+
+// EmbeddedWorkerDevToolsManager is used instead of WorkerDevToolsManager when
+// "enable-embedded-shared-worker" flag is set.
+// This class lives on UI thread.
+class CONTENT_EXPORT EmbeddedWorkerDevToolsManager {
+ public:
+ typedef std::pair<int, int> WorkerId;
+ class EmbeddedWorkerDevToolsAgentHost;
+
+ class ServiceWorkerIdentifier {
+ public:
+ ServiceWorkerIdentifier(
+ const ServiceWorkerContextCore* const service_worker_context,
+ int64 service_worker_version_id);
+ explicit ServiceWorkerIdentifier(const ServiceWorkerIdentifier& other);
+ ~ServiceWorkerIdentifier() {}
+
+ bool Matches(const ServiceWorkerIdentifier& other) const;
+
+ private:
+ const ServiceWorkerContextCore* const service_worker_context_;
+ const int64 service_worker_version_id_;
+ };
+
+ // Returns the EmbeddedWorkerDevToolsManager singleton.
+ static EmbeddedWorkerDevToolsManager* GetInstance();
+
+ DevToolsAgentHost* GetDevToolsAgentHostForWorker(int worker_process_id,
+ int worker_route_id);
+ DevToolsAgentHost* GetDevToolsAgentHostForServiceWorker(
+ const ServiceWorkerIdentifier& service_worker_id);
+
+ // Returns true when the worker must be paused on start because a DevTool
+ // window for the same former SharedWorkerInstance is still opened.
+ bool SharedWorkerCreated(int worker_process_id,
+ int worker_route_id,
+ const SharedWorkerInstance& instance);
+ // Returns true when the worker must be paused on start because a DevTool
+ // window for the same former ServiceWorkerIdentifier is still opened or
+ // debug-on-start is enabled in chrome://serviceworker-internals.
+ bool ServiceWorkerCreated(int worker_process_id,
+ int worker_route_id,
+ const ServiceWorkerIdentifier& service_worker_id);
+ void WorkerContextStarted(int worker_process_id, int worker_route_id);
+ void WorkerDestroyed(int worker_process_id, int worker_route_id);
+
+ void set_debug_service_worker_on_start(bool debug_on_start) {
+ debug_service_worker_on_start_ = debug_on_start;
+ }
+ bool debug_service_worker_on_start() const {
+ return debug_service_worker_on_start_;
+ }
+
+ private:
+ friend struct DefaultSingletonTraits<EmbeddedWorkerDevToolsManager>;
+ friend class EmbeddedWorkerDevToolsManagerTest;
+ FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerDevToolsManagerTest, BasicTest);
+ FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerDevToolsManagerTest, AttachTest);
+
+ enum WorkerState {
+ WORKER_UNINSPECTED,
+ WORKER_INSPECTED,
+ WORKER_TERMINATED,
+ WORKER_PAUSED_FOR_DEBUG_ON_START,
+ WORKER_PAUSED_FOR_REATTACH,
+ };
+
+ class WorkerInfo {
+ public:
+ // Creates WorkerInfo for SharedWorker.
+ explicit WorkerInfo(const SharedWorkerInstance& instance);
+ // Creates WorkerInfo for ServiceWorker.
+ explicit WorkerInfo(const ServiceWorkerIdentifier& service_worker_id);
+ ~WorkerInfo();
+
+ WorkerState state() { return state_; }
+ void set_state(WorkerState new_state) { state_ = new_state; }
+ EmbeddedWorkerDevToolsAgentHost* agent_host() { return agent_host_; }
+ void set_agent_host(EmbeddedWorkerDevToolsAgentHost* agent_host) {
+ agent_host_ = agent_host;
+ }
+ bool Matches(const SharedWorkerInstance& other);
+ bool Matches(const ServiceWorkerIdentifier& other);
+
+ private:
+ scoped_ptr<SharedWorkerInstance> shared_worker_instance_;
+ scoped_ptr<ServiceWorkerIdentifier> service_worker_id_;
+ WorkerState state_;
+ EmbeddedWorkerDevToolsAgentHost* agent_host_;
+ };
+
+ typedef base::ScopedPtrHashMap<WorkerId, WorkerInfo> WorkerInfoMap;
+
+ EmbeddedWorkerDevToolsManager();
+ virtual ~EmbeddedWorkerDevToolsManager();
+
+ void RemoveInspectedWorkerData(EmbeddedWorkerDevToolsAgentHost* agent_host);
+
+ WorkerInfoMap::iterator FindExistingSharedWorkerInfo(
+ const SharedWorkerInstance& instance);
+ WorkerInfoMap::iterator FindExistingServiceWorkerInfo(
+ const ServiceWorkerIdentifier& service_worker_id);
+
+ void MoveToPausedState(const WorkerId& id, const WorkerInfoMap::iterator& it);
+
+ // Resets to its initial state as if newly created.
+ void ResetForTesting();
+
+ WorkerInfoMap workers_;
+
+ bool debug_service_worker_on_start_;
+
+ DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerDevToolsManager);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DEVTOOLS_EMBEDDED_WORKER_DEVTOOLS_MANAGER_H_
diff --git a/chromium/content/browser/devtools/embedded_worker_devtools_manager_unittest.cc b/chromium/content/browser/devtools/embedded_worker_devtools_manager_unittest.cc
new file mode 100644
index 00000000000..69b23052425
--- /dev/null
+++ b/chromium/content/browser/devtools/embedded_worker_devtools_manager_unittest.cc
@@ -0,0 +1,272 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/devtools/embedded_worker_devtools_manager.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "content/browser/browser_thread_impl.h"
+#include "content/browser/devtools/devtools_manager_impl.h"
+#include "content/browser/shared_worker/shared_worker_instance.h"
+#include "content/browser/worker_host/worker_storage_partition.h"
+#include "content/public/browser/devtools_agent_host.h"
+#include "content/public/browser/devtools_client_host.h"
+#include "content/public/test/test_browser_context.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+class TestDevToolsClientHost : public DevToolsClientHost {
+ public:
+ TestDevToolsClientHost() {}
+ virtual ~TestDevToolsClientHost() {}
+ virtual void DispatchOnInspectorFrontend(
+ const std::string& message) OVERRIDE {}
+ virtual void InspectedContentsClosing() OVERRIDE {}
+ virtual void ReplacedWithAnotherClient() OVERRIDE {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestDevToolsClientHost);
+};
+}
+
+class EmbeddedWorkerDevToolsManagerTest : public testing::Test {
+ public:
+ EmbeddedWorkerDevToolsManagerTest()
+ : ui_thread_(BrowserThread::UI, &message_loop_),
+ browser_context_(new TestBrowserContext()),
+ partition_(
+ new WorkerStoragePartition(browser_context_->GetRequestContext(),
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL)),
+ partition_id_(*partition_.get()) {}
+
+ protected:
+ virtual void SetUp() OVERRIDE {
+ manager_ = EmbeddedWorkerDevToolsManager::GetInstance();
+ }
+ virtual void TearDown() OVERRIDE {
+ EmbeddedWorkerDevToolsManager::GetInstance()->ResetForTesting();
+ }
+
+ void CheckWorkerState(int worker_process_id,
+ int worker_route_id,
+ EmbeddedWorkerDevToolsManager::WorkerState state) {
+ const EmbeddedWorkerDevToolsManager::WorkerId id(worker_process_id,
+ worker_route_id);
+ EmbeddedWorkerDevToolsManager::WorkerInfoMap::iterator it =
+ manager_->workers_.find(id);
+ EXPECT_TRUE(manager_->workers_.end() != it);
+ EXPECT_EQ(state, it->second->state());
+ }
+
+ void CheckWorkerNotExist(int worker_process_id, int worker_route_id) {
+ const EmbeddedWorkerDevToolsManager::WorkerId id(worker_process_id,
+ worker_route_id);
+ EXPECT_TRUE(manager_->workers_.end() == manager_->workers_.find(id));
+ }
+
+ void CheckWorkerCount(size_t size) {
+ EXPECT_EQ(size, manager_->workers_.size());
+ }
+
+ void RegisterDevToolsClientHostFor(DevToolsAgentHost* agent_host,
+ DevToolsClientHost* client_host) {
+ DevToolsManagerImpl::GetInstance()->RegisterDevToolsClientHostFor(
+ agent_host, client_host);
+ }
+
+ void ClientHostClosing(DevToolsClientHost* client_host) {
+ DevToolsManagerImpl::GetInstance()->ClientHostClosing(client_host);
+ }
+
+ base::MessageLoopForIO message_loop_;
+ BrowserThreadImpl ui_thread_;
+ scoped_ptr<TestBrowserContext> browser_context_;
+ scoped_ptr<WorkerStoragePartition> partition_;
+ const WorkerStoragePartitionId partition_id_;
+ EmbeddedWorkerDevToolsManager* manager_;
+};
+
+TEST_F(EmbeddedWorkerDevToolsManagerTest, BasicTest) {
+ scoped_refptr<DevToolsAgentHost> agent_host;
+
+ SharedWorkerInstance instance1(GURL("http://example.com/w.js"),
+ base::string16(),
+ base::string16(),
+ blink::WebContentSecurityPolicyTypeReport,
+ browser_context_->GetResourceContext(),
+ partition_id_);
+
+ agent_host = manager_->GetDevToolsAgentHostForWorker(1, 1);
+ EXPECT_FALSE(agent_host.get());
+
+ // Created -> Started -> Destroyed
+ CheckWorkerNotExist(1, 1);
+ manager_->SharedWorkerCreated(1, 1, instance1);
+ CheckWorkerState(1, 1, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+ manager_->WorkerContextStarted(1, 1);
+ CheckWorkerState(1, 1, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+ manager_->WorkerDestroyed(1, 1);
+ CheckWorkerNotExist(1, 1);
+
+ // Created -> GetDevToolsAgentHost -> Started -> Destroyed
+ CheckWorkerNotExist(1, 2);
+ manager_->SharedWorkerCreated(1, 2, instance1);
+ CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+ agent_host = manager_->GetDevToolsAgentHostForWorker(1, 2);
+ EXPECT_TRUE(agent_host.get());
+ CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+ EXPECT_EQ(agent_host.get(), manager_->GetDevToolsAgentHostForWorker(1, 2));
+ manager_->WorkerContextStarted(1, 2);
+ CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+ manager_->WorkerDestroyed(1, 2);
+ CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
+ agent_host = NULL;
+ CheckWorkerNotExist(1, 2);
+
+ // Created -> Started -> GetDevToolsAgentHost -> Destroyed
+ CheckWorkerNotExist(1, 3);
+ manager_->SharedWorkerCreated(1, 3, instance1);
+ CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+ manager_->WorkerContextStarted(1, 3);
+ CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+ agent_host = manager_->GetDevToolsAgentHostForWorker(1, 3);
+ EXPECT_TRUE(agent_host.get());
+ CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+ manager_->WorkerDestroyed(1, 3);
+ CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
+ agent_host = NULL;
+ CheckWorkerNotExist(1, 3);
+
+ // Created -> Destroyed
+ CheckWorkerNotExist(1, 4);
+ manager_->SharedWorkerCreated(1, 4, instance1);
+ CheckWorkerState(1, 4, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+ manager_->WorkerDestroyed(1, 4);
+ CheckWorkerNotExist(1, 4);
+
+ // Created -> GetDevToolsAgentHost -> Destroyed
+ CheckWorkerNotExist(1, 5);
+ manager_->SharedWorkerCreated(1, 5, instance1);
+ CheckWorkerState(1, 5, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+ agent_host = manager_->GetDevToolsAgentHostForWorker(1, 5);
+ EXPECT_TRUE(agent_host.get());
+ CheckWorkerState(1, 5, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+ manager_->WorkerDestroyed(1, 5);
+ CheckWorkerState(1, 5, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
+ agent_host = NULL;
+ CheckWorkerNotExist(1, 5);
+
+ // Created -> GetDevToolsAgentHost -> Free agent_host -> Destroyed
+ CheckWorkerNotExist(1, 6);
+ manager_->SharedWorkerCreated(1, 6, instance1);
+ CheckWorkerState(1, 6, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+ agent_host = manager_->GetDevToolsAgentHostForWorker(1, 6);
+ EXPECT_TRUE(agent_host.get());
+ CheckWorkerState(1, 6, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+ agent_host = NULL;
+ manager_->WorkerDestroyed(1, 6);
+ CheckWorkerNotExist(1, 6);
+}
+
+TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) {
+ scoped_refptr<DevToolsAgentHost> agent_host1;
+ scoped_refptr<DevToolsAgentHost> agent_host2;
+
+ SharedWorkerInstance instance1(GURL("http://example.com/w1.js"),
+ base::string16(),
+ base::string16(),
+ blink::WebContentSecurityPolicyTypeReport,
+ browser_context_->GetResourceContext(),
+ partition_id_);
+ SharedWorkerInstance instance2(GURL("http://example.com/w2.js"),
+ base::string16(),
+ base::string16(),
+ blink::WebContentSecurityPolicyTypeReport,
+ browser_context_->GetResourceContext(),
+ partition_id_);
+
+ // Created -> GetDevToolsAgentHost -> Register -> Started -> Destroyed
+ scoped_ptr<TestDevToolsClientHost> client_host1(new TestDevToolsClientHost());
+ CheckWorkerNotExist(2, 1);
+ manager_->SharedWorkerCreated(2, 1, instance1);
+ CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+ agent_host1 = manager_->GetDevToolsAgentHostForWorker(2, 1);
+ EXPECT_TRUE(agent_host1.get());
+ CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+ EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 1));
+ RegisterDevToolsClientHostFor(agent_host1.get(), client_host1.get());
+ CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+ manager_->WorkerContextStarted(2, 1);
+ CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+ manager_->WorkerDestroyed(2, 1);
+ CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
+ EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 1));
+
+ // Created -> Started -> GetDevToolsAgentHost -> Register -> Destroyed
+ scoped_ptr<TestDevToolsClientHost> client_host2(new TestDevToolsClientHost());
+ manager_->SharedWorkerCreated(2, 2, instance2);
+ CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+ manager_->WorkerContextStarted(2, 2);
+ CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
+ agent_host2 = manager_->GetDevToolsAgentHostForWorker(2, 2);
+ EXPECT_TRUE(agent_host2.get());
+ EXPECT_NE(agent_host1.get(), agent_host2.get());
+ EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 2));
+ CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+ RegisterDevToolsClientHostFor(agent_host2.get(), client_host2.get());
+ CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+ manager_->WorkerDestroyed(2, 2);
+ CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
+ EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 2));
+
+ // Re-created -> Started -> ClientHostClosing -> Destroyed
+ CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
+ manager_->SharedWorkerCreated(2, 3, instance1);
+ CheckWorkerNotExist(2, 1);
+ CheckWorkerState(
+ 2, 3, EmbeddedWorkerDevToolsManager::WORKER_PAUSED_FOR_REATTACH);
+ EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 3));
+ manager_->WorkerContextStarted(2, 3);
+ CheckWorkerState(2, 3, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
+ ClientHostClosing(client_host1.get());
+ manager_->WorkerDestroyed(2, 3);
+ CheckWorkerState(2, 3, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
+ agent_host1 = NULL;
+ CheckWorkerNotExist(2, 3);
+
+ // Re-created -> Destroyed
+ CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
+ manager_->SharedWorkerCreated(2, 4, instance2);
+ CheckWorkerNotExist(2, 2);
+ CheckWorkerState(
+ 2, 4, EmbeddedWorkerDevToolsManager::WORKER_PAUSED_FOR_REATTACH);
+ EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 4));
+ manager_->WorkerDestroyed(2, 4);
+ CheckWorkerNotExist(2, 4);
+ CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
+
+ // Re-created -> ClientHostClosing -> Destroyed
+ manager_->SharedWorkerCreated(2, 5, instance2);
+ CheckWorkerNotExist(2, 2);
+ CheckWorkerState(
+ 2, 5, EmbeddedWorkerDevToolsManager::WORKER_PAUSED_FOR_REATTACH);
+ EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 5));
+ ClientHostClosing(client_host2.get());
+ CheckWorkerCount(1);
+ agent_host2 = NULL;
+ CheckWorkerCount(1);
+ manager_->WorkerDestroyed(2, 5);
+ CheckWorkerCount(0);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/devtools/forwarding_agent_host.cc b/chromium/content/browser/devtools/forwarding_agent_host.cc
new file mode 100644
index 00000000000..f1524e1b7e1
--- /dev/null
+++ b/chromium/content/browser/devtools/forwarding_agent_host.cc
@@ -0,0 +1,41 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/devtools/forwarding_agent_host.h"
+
+#include "content/browser/devtools/devtools_manager_impl.h"
+
+namespace content {
+
+ForwardingAgentHost::ForwardingAgentHost(
+ DevToolsExternalAgentProxyDelegate* delegate)
+ : delegate_(delegate) {
+}
+
+ForwardingAgentHost::~ForwardingAgentHost() {
+}
+
+void ForwardingAgentHost::DispatchOnClientHost(const std::string& message) {
+ DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(
+ this, message);
+}
+
+void ForwardingAgentHost::ConnectionClosed() {
+ NotifyCloseListener();
+}
+
+void ForwardingAgentHost::Attach() {
+ delegate_->Attach(this);
+}
+
+void ForwardingAgentHost::Detach() {
+ delegate_->Detach();
+}
+
+void ForwardingAgentHost::DispatchOnInspectorBackend(
+ const std::string& message) {
+ delegate_->SendMessageToBackend(message);
+}
+
+} // content
diff --git a/chromium/content/browser/devtools/forwarding_agent_host.h b/chromium/content/browser/devtools/forwarding_agent_host.h
new file mode 100644
index 00000000000..81e4aed5419
--- /dev/null
+++ b/chromium/content/browser/devtools/forwarding_agent_host.h
@@ -0,0 +1,39 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DEVTOOLS_FORWARDING_AGENT_HOST_H
+#define CONTENT_BROWSER_DEVTOOLS_FORWARDING_AGENT_HOST_H
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/browser/devtools/devtools_agent_host_impl.h"
+#include "content/public/browser/devtools_external_agent_proxy.h"
+#include "content/public/browser/devtools_external_agent_proxy_delegate.h"
+
+namespace content {
+
+class ForwardingAgentHost
+ : public DevToolsAgentHostImpl,
+ public DevToolsExternalAgentProxy {
+ public:
+ ForwardingAgentHost(DevToolsExternalAgentProxyDelegate* delegate);
+
+ private:
+ virtual ~ForwardingAgentHost();
+
+ // DevToolsExternalAgentProxy implementation.
+ virtual void DispatchOnClientHost(const std::string& message) OVERRIDE;
+ virtual void ConnectionClosed() OVERRIDE;
+
+ // DevToolsAgentHostImpl implementation.
+ virtual void Attach() OVERRIDE;
+ virtual void Detach() OVERRIDE;
+ virtual void DispatchOnInspectorBackend(const std::string& message) OVERRIDE;
+
+ scoped_ptr<DevToolsExternalAgentProxyDelegate> delegate_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DEVTOOLS_FORWARDING_AGENT_HOST_H
diff --git a/chromium/content/browser/devtools/ipc_devtools_agent_host.cc b/chromium/content/browser/devtools/ipc_devtools_agent_host.cc
index c7cd3c386f8..294a679c7f6 100644
--- a/chromium/content/browser/devtools/ipc_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/ipc_devtools_agent_host.cc
@@ -9,7 +9,7 @@
namespace content {
void IPCDevToolsAgentHost::Attach() {
- SendMessageToAgent(new DevToolsAgentMsg_Attach(MSG_ROUTING_NONE));
+ SendMessageToAgent(new DevToolsAgentMsg_Attach(MSG_ROUTING_NONE, GetId()));
OnClientAttached();
}
@@ -26,7 +26,7 @@ void IPCDevToolsAgentHost::DispatchOnInspectorBackend(
void IPCDevToolsAgentHost::InspectElement(int x, int y) {
SendMessageToAgent(new DevToolsAgentMsg_InspectElement(MSG_ROUTING_NONE,
- x, y));
+ GetId(), x, y));
}
IPCDevToolsAgentHost::~IPCDevToolsAgentHost() {
@@ -34,8 +34,7 @@ IPCDevToolsAgentHost::~IPCDevToolsAgentHost() {
void IPCDevToolsAgentHost::Reattach(const std::string& saved_agent_state) {
SendMessageToAgent(new DevToolsAgentMsg_Reattach(
- MSG_ROUTING_NONE,
- saved_agent_state));
+ MSG_ROUTING_NONE, GetId(), saved_agent_state));
OnClientAttached();
}
diff --git a/chromium/content/browser/devtools/render_view_devtools_agent_host.cc b/chromium/content/browser/devtools/render_view_devtools_agent_host.cc
index 39ced5eb581..82df7ed2f0d 100644
--- a/chromium/content/browser/devtools/render_view_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/render_view_devtools_agent_host.cc
@@ -8,6 +8,7 @@
#include "base/lazy_instance.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/devtools/devtools_manager_impl.h"
+#include "content/browser/devtools/devtools_power_handler.h"
#include "content/browser/devtools/devtools_protocol.h"
#include "content/browser/devtools/devtools_protocol_constants.h"
#include "content/browser/devtools/devtools_tracing_handler.h"
@@ -19,6 +20,7 @@
#include "content/common/devtools_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/devtools_manager_delegate.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_widget_host_iterator.h"
@@ -35,6 +37,22 @@ typedef std::vector<RenderViewDevToolsAgentHost*> Instances;
namespace {
base::LazyInstance<Instances>::Leaky g_instances = LAZY_INSTANCE_INITIALIZER;
+//Returns RenderViewDevToolsAgentHost attached to any of RenderViewHost
+//instances associated with |web_contents|
+static RenderViewDevToolsAgentHost* FindAgentHost(WebContents* web_contents) {
+ if (g_instances == NULL)
+ return NULL;
+ RenderViewHostDelegate* delegate =
+ static_cast<WebContentsImpl*>(web_contents);
+ for (Instances::iterator it = g_instances.Get().begin();
+ it != g_instances.Get().end(); ++it) {
+ RenderViewHost* rvh = (*it)->render_view_host();
+ if (rvh && rvh->GetDelegate() == delegate)
+ return *it;
+ }
+ return NULL;
+}
+
static RenderViewDevToolsAgentHost* FindAgentHost(RenderViewHost* rvh) {
if (g_instances == NULL)
return NULL;
@@ -48,6 +66,14 @@ static RenderViewDevToolsAgentHost* FindAgentHost(RenderViewHost* rvh) {
} // namespace
+scoped_refptr<DevToolsAgentHost>
+DevToolsAgentHost::GetOrCreateFor(WebContents* web_contents) {
+ RenderViewDevToolsAgentHost* result = FindAgentHost(web_contents);
+ if (!result)
+ result = new RenderViewDevToolsAgentHost(web_contents->GetRenderViewHost());
+ return result;
+}
+
// static
scoped_refptr<DevToolsAgentHost>
DevToolsAgentHost::GetOrCreateFor(RenderViewHost* rvh) {
@@ -96,10 +122,20 @@ std::vector<RenderViewHost*> DevToolsAgentHost::GetValidRenderViewHosts() {
RenderViewHost* rvh = RenderViewHost::From(widget);
WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
+ if (!web_contents)
+ continue;
+
// Don't report a RenderViewHost if it is not the current RenderViewHost
- // for some WebContents.
- if (!web_contents || rvh != web_contents->GetRenderViewHost())
+ // for some WebContents (this filters out pre-render RVHs and similar).
+ // However report a RenderViewHost created for an out of process iframe.
+ // TODO (kaznacheev): Revisit this when it is clear how OOP iframes
+ // interact with pre-rendering.
+ // TODO (kaznacheev): GetMainFrame() call is a temporary hack. Iterate over
+ // all RenderFrameHost instances when multiple OOP frames are supported.
+ if (rvh != web_contents->GetRenderViewHost() &&
+ !rvh->GetMainFrame()->IsCrossProcessSubframe()) {
continue;
+ }
result.push_back(rvh);
}
@@ -117,18 +153,28 @@ void RenderViewDevToolsAgentHost::OnCancelPendingNavigation(
agent_host->ConnectRenderViewHost(current);
}
-RenderViewDevToolsAgentHost::RenderViewDevToolsAgentHost(
- RenderViewHost* rvh)
+// static
+bool RenderViewDevToolsAgentHost::DispatchIPCMessage(
+ RenderViewHost* source,
+ const IPC::Message& message) {
+ RenderViewDevToolsAgentHost* agent_host = FindAgentHost(source);
+ return agent_host && agent_host->DispatchIPCMessage(message);
+}
+
+RenderViewDevToolsAgentHost::RenderViewDevToolsAgentHost(RenderViewHost* rvh)
: render_view_host_(NULL),
overrides_handler_(new RendererOverridesHandler(this)),
- tracing_handler_(new DevToolsTracingHandler())
- {
+ tracing_handler_(
+ new DevToolsTracingHandler(DevToolsTracingHandler::Renderer)),
+ power_handler_(new DevToolsPowerHandler()),
+ reattaching_(false) {
SetRenderViewHost(rvh);
DevToolsProtocol::Notifier notifier(base::Bind(
&RenderViewDevToolsAgentHost::OnDispatchOnInspectorFrontend,
base::Unretained(this)));
overrides_handler_->SetNotifier(notifier);
tracing_handler_->SetNotifier(notifier);
+ power_handler_->SetNotifier(notifier);
g_instances.Get().push_back(this);
AddRef(); // Balanced in RenderViewHostDestroyed.
}
@@ -140,14 +186,30 @@ RenderViewHost* RenderViewDevToolsAgentHost::GetRenderViewHost() {
void RenderViewDevToolsAgentHost::DispatchOnInspectorBackend(
const std::string& message) {
std::string error_message;
+
+ scoped_ptr<base::DictionaryValue> message_dict(
+ DevToolsProtocol::ParseMessage(message, &error_message));
scoped_refptr<DevToolsProtocol::Command> command =
- DevToolsProtocol::ParseCommand(message, &error_message);
+ DevToolsProtocol::ParseCommand(message_dict.get(), &error_message);
if (command) {
- scoped_refptr<DevToolsProtocol::Response> overridden_response =
- overrides_handler_->HandleCommand(command);
+ scoped_refptr<DevToolsProtocol::Response> overridden_response;
+
+ DevToolsManagerDelegate* delegate =
+ DevToolsManagerImpl::GetInstance()->delegate();
+ if (delegate) {
+ scoped_ptr<base::DictionaryValue> overridden_response_value(
+ delegate->HandleCommand(this, message_dict.get()));
+ if (overridden_response_value)
+ overridden_response = DevToolsProtocol::ParseResponse(
+ overridden_response_value.get());
+ }
+ if (!overridden_response)
+ overridden_response = overrides_handler_->HandleCommand(command);
if (!overridden_response)
overridden_response = tracing_handler_->HandleCommand(command);
+ if (!overridden_response)
+ overridden_response = power_handler_->HandleCommand(command);
if (overridden_response) {
if (!overridden_response->is_async_promise())
OnDispatchOnInspectorFrontend(overridden_response->Serialize());
@@ -169,12 +231,17 @@ void RenderViewDevToolsAgentHost::OnClientAttached() {
if (!render_view_host_)
return;
- ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadRawCookies(
- render_view_host_->GetProcess()->GetID());
+ InnerOnClientAttached();
// TODO(kaznacheev): Move this call back to DevToolsManagerImpl when
// extensions::ProcessManager no longer relies on this notification.
- DevToolsManagerImpl::GetInstance()->NotifyObservers(this, true);
+ if (!reattaching_)
+ DevToolsManagerImpl::GetInstance()->NotifyObservers(this, true);
+}
+
+void RenderViewDevToolsAgentHost::InnerOnClientAttached() {
+ ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadRawCookies(
+ render_view_host_->GetProcess()->GetID());
#if defined(OS_ANDROID)
power_save_blocker_.reset(
@@ -194,6 +261,7 @@ void RenderViewDevToolsAgentHost::OnClientDetached() {
power_save_blocker_.reset();
#endif
overrides_handler_->OnClientDetached();
+ tracing_handler_->OnClientDetached();
ClientDetachedFromRenderer();
}
@@ -201,6 +269,15 @@ void RenderViewDevToolsAgentHost::ClientDetachedFromRenderer() {
if (!render_view_host_)
return;
+ InnerClientDetachedFromRenderer();
+
+ // TODO(kaznacheev): Move this call back to DevToolsManagerImpl when
+ // extensions::ProcessManager no longer relies on this notification.
+ if (!reattaching_)
+ DevToolsManagerImpl::GetInstance()->NotifyObservers(this, false);
+}
+
+void RenderViewDevToolsAgentHost::InnerClientDetachedFromRenderer() {
bool process_has_agents = false;
RenderProcessHost* render_process_host = render_view_host_->GetProcess();
for (Instances::iterator it = g_instances.Get().begin();
@@ -217,10 +294,6 @@ void RenderViewDevToolsAgentHost::ClientDetachedFromRenderer() {
ChildProcessSecurityPolicyImpl::GetInstance()->RevokeReadRawCookies(
render_process_host->GetID());
}
-
- // TODO(kaznacheev): Move this call back to DevToolsManagerImpl when
- // extensions::ProcessManager no longer relies on this notification.
- DevToolsManagerImpl::GetInstance()->NotifyObservers(this, false);
}
RenderViewDevToolsAgentHost::~RenderViewDevToolsAgentHost() {
@@ -240,8 +313,7 @@ void RenderViewDevToolsAgentHost::AboutToNavigateRenderView(
render_view_host_)->render_view_termination_status() ==
base::TERMINATION_STATUS_STILL_RUNNING)
return;
- DisconnectRenderViewHost();
- ConnectRenderViewHost(dest_rvh);
+ ReattachToRenderViewHost(dest_rvh);
}
void RenderViewDevToolsAgentHost::RenderViewHostChanged(
@@ -250,11 +322,19 @@ void RenderViewDevToolsAgentHost::RenderViewHostChanged(
if (new_host != render_view_host_) {
// AboutToNavigateRenderView was not called for renderer-initiated
// navigation.
- DisconnectRenderViewHost();
- ConnectRenderViewHost(new_host);
+ ReattachToRenderViewHost(new_host);
}
}
+void
+RenderViewDevToolsAgentHost::ReattachToRenderViewHost(RenderViewHost* rvh) {
+ DCHECK(!reattaching_);
+ reattaching_ = true;
+ DisconnectRenderViewHost();
+ ConnectRenderViewHost(rvh);
+ reattaching_ = false;
+}
+
void RenderViewDevToolsAgentHost::RenderViewDeleted(RenderViewHost* rvh) {
if (rvh != render_view_host_)
return;
@@ -272,6 +352,9 @@ void RenderViewDevToolsAgentHost::RenderProcessGone(
case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
case base::TERMINATION_STATUS_PROCESS_CRASHED:
+#if defined(OS_ANDROID)
+ case base::TERMINATION_STATUS_OOM_PROTECTED:
+#endif
RenderViewCrashed();
break;
default:
@@ -341,7 +424,7 @@ void RenderViewDevToolsAgentHost::RenderViewCrashed() {
DispatchOnInspectorFrontend(this, notification->Serialize());
}
-bool RenderViewDevToolsAgentHost::OnMessageReceived(
+bool RenderViewDevToolsAgentHost::DispatchIPCMessage(
const IPC::Message& msg) {
if (!render_view_host_)
return false;
@@ -352,9 +435,6 @@ bool RenderViewDevToolsAgentHost::OnMessageReceived(
OnDispatchOnInspectorFrontend)
IPC_MESSAGE_HANDLER(DevToolsHostMsg_SaveAgentRuntimeState,
OnSaveAgentRuntimeState)
- IPC_MESSAGE_HANDLER(DevToolsHostMsg_ClearBrowserCache, OnClearBrowserCache)
- IPC_MESSAGE_HANDLER(DevToolsHostMsg_ClearBrowserCookies,
- OnClearBrowserCookies)
IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_SwapCompositorFrame,
handled = false; OnSwapCompositorFrame(msg))
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -392,14 +472,4 @@ void RenderViewDevToolsAgentHost::OnDispatchOnInspectorFrontend(
this, message);
}
-void RenderViewDevToolsAgentHost::OnClearBrowserCache() {
- if (render_view_host_)
- GetContentClient()->browser()->ClearCache(render_view_host_);
-}
-
-void RenderViewDevToolsAgentHost::OnClearBrowserCookies() {
- if (render_view_host_)
- GetContentClient()->browser()->ClearCookies(render_view_host_);
-}
-
} // namespace content
diff --git a/chromium/content/browser/devtools/render_view_devtools_agent_host.h b/chromium/content/browser/devtools/render_view_devtools_agent_host.h
index 88ba70cc81a..f4e9baf4a5f 100644
--- a/chromium/content/browser/devtools/render_view_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/render_view_devtools_agent_host.h
@@ -22,6 +22,7 @@ class CompositorFrameMetadata;
namespace content {
+class DevToolsPowerHandler;
class DevToolsTracingHandler;
class RendererOverridesHandler;
class RenderViewHost;
@@ -38,6 +39,9 @@ class CONTENT_EXPORT RenderViewDevToolsAgentHost
static void OnCancelPendingNavigation(RenderViewHost* pending,
RenderViewHost* current);
+ static bool DispatchIPCMessage(RenderViewHost* source,
+ const IPC::Message& message);
+
RenderViewDevToolsAgentHost(RenderViewHost*);
RenderViewHost* render_view_host() { return render_view_host_; }
@@ -68,13 +72,16 @@ class CONTENT_EXPORT RenderViewDevToolsAgentHost
virtual void RenderViewDeleted(RenderViewHost* rvh) OVERRIDE;
virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
virtual void DidAttachInterstitialPage() OVERRIDE;
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
// NotificationObserver overrides:
virtual void Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) OVERRIDE;
+ void ReattachToRenderViewHost(RenderViewHost* rvh);
+
+ bool DispatchIPCMessage(const IPC::Message& message);
+
void SetRenderViewHost(RenderViewHost* rvh);
void ClearRenderViewHost();
@@ -83,19 +90,22 @@ class CONTENT_EXPORT RenderViewDevToolsAgentHost
void OnDispatchOnInspectorFrontend(const std::string& message);
void OnSaveAgentRuntimeState(const std::string& state);
- void OnClearBrowserCache();
- void OnClearBrowserCookies();
void ClientDetachedFromRenderer();
+ void InnerOnClientAttached();
+ void InnerClientDetachedFromRenderer();
+
RenderViewHost* render_view_host_;
scoped_ptr<RendererOverridesHandler> overrides_handler_;
scoped_ptr<DevToolsTracingHandler> tracing_handler_;
+ scoped_ptr<DevToolsPowerHandler> power_handler_;
#if defined(OS_ANDROID)
scoped_ptr<PowerSaveBlockerImpl> power_save_blocker_;
#endif
std::string state_;
NotificationRegistrar registrar_;
+ bool reattaching_;
DISALLOW_COPY_AND_ASSIGN(RenderViewDevToolsAgentHost);
};
diff --git a/chromium/content/browser/devtools/renderer_overrides_handler.cc b/chromium/content/browser/devtools/renderer_overrides_handler.cc
index 4901f34cc12..7370275cd45 100644
--- a/chromium/content/browser/devtools/renderer_overrides_handler.cc
+++ b/chromium/content/browser/devtools/renderer_overrides_handler.cc
@@ -13,6 +13,7 @@
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
#include "base/strings/string16.h"
+#include "base/thread_task_runner_handle.h"
#include "base/values.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/devtools/devtools_protocol_constants.h"
@@ -20,9 +21,10 @@
#include "content/browser/renderer_host/dip_util.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/common/view_messages.h"
-#include "content/port/browser/render_widget_host_view_port.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/javascript_dialog_manager.h"
#include "content/public/browser/navigation_controller.h"
@@ -41,6 +43,8 @@
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/codec/png_codec.h"
+#include "ui/gfx/display.h"
+#include "ui/gfx/screen.h"
#include "ui/gfx/size_conversions.h"
#include "ui/snapshot/snapshot.h"
#include "url/gurl.h"
@@ -91,6 +95,16 @@ RendererOverridesHandler::RendererOverridesHandler(DevToolsAgentHost* agent)
&RendererOverridesHandler::GrantPermissionsForSetFileInputFiles,
base::Unretained(this)));
RegisterCommandHandler(
+ devtools::Network::clearBrowserCache::kName,
+ base::Bind(
+ &RendererOverridesHandler::ClearBrowserCache,
+ base::Unretained(this)));
+ RegisterCommandHandler(
+ devtools::Network::clearBrowserCookies::kName,
+ base::Bind(
+ &RendererOverridesHandler::ClearBrowserCookies,
+ base::Unretained(this)));
+ RegisterCommandHandler(
devtools::Page::disable::kName,
base::Bind(
&RendererOverridesHandler::PageDisable, base::Unretained(this)));
@@ -192,19 +206,22 @@ void RendererOverridesHandler::InnerSwapCompositorFrame() {
double scale = 1;
ParseCaptureParameters(screencast_command_.get(), &format, &quality, &scale);
- RenderWidgetHostViewPort* view_port =
- RenderWidgetHostViewPort::FromRWHV(host->GetView());
+ const gfx::Display& display =
+ gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
+ float device_scale_factor = display.device_scale_factor();
gfx::Rect view_bounds = host->GetView()->GetViewBounds();
- gfx::Size snapshot_size = gfx::ToFlooredSize(
- gfx::ScaleSize(view_bounds.size(), scale));
+ gfx::Size snapshot_size(gfx::ToCeiledSize(
+ gfx::ScaleSize(view_bounds.size(), scale / device_scale_factor)));
- view_port->CopyFromCompositingSurface(
+ RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
+ host->GetView());
+ view->CopyFromCompositingSurface(
view_bounds, snapshot_size,
- base::Bind(&RendererOverridesHandler::ScreenshotCaptured,
+ base::Bind(&RendererOverridesHandler::ScreencastFrameCaptured,
weak_factory_.GetWeakPtr(),
- scoped_refptr<DevToolsProtocol::Command>(), format, quality,
- last_compositor_frame_metadata_));
+ format, quality, last_compositor_frame_metadata_),
+ SkBitmap::kARGB_8888_Config);
}
void RendererOverridesHandler::ParseCaptureParameters(
@@ -218,13 +235,13 @@ void RendererOverridesHandler::ParseCaptureParameters(
double max_height = -1;
base::DictionaryValue* params = command->params();
if (params) {
- params->GetString(devtools::Page::captureScreenshot::kParamFormat,
+ params->GetString(devtools::Page::startScreencast::kParamFormat,
format);
- params->GetInteger(devtools::Page::captureScreenshot::kParamQuality,
+ params->GetInteger(devtools::Page::startScreencast::kParamQuality,
quality);
- params->GetDouble(devtools::Page::captureScreenshot::kParamMaxWidth,
+ params->GetDouble(devtools::Page::startScreencast::kParamMaxWidth,
&max_width);
- params->GetDouble(devtools::Page::captureScreenshot::kParamMaxHeight,
+ params->GetDouble(devtools::Page::startScreencast::kParamMaxHeight,
&max_height);
}
@@ -246,6 +263,20 @@ void RendererOverridesHandler::ParseCaptureParameters(
*scale = 5;
}
+base::DictionaryValue* RendererOverridesHandler::CreateScreenshotResponse(
+ const std::vector<unsigned char>& png_data) {
+ std::string base_64_data;
+ base::Base64Encode(
+ base::StringPiece(reinterpret_cast<const char*>(&png_data[0]),
+ png_data.size()),
+ &base_64_data);
+
+ base::DictionaryValue* response = new base::DictionaryValue();
+ response->SetString(
+ devtools::Page::captureScreenshot::kResponseData, base_64_data);
+ return response;
+}
+
// DOM agent handlers --------------------------------------------------------
scoped_refptr<DevToolsProtocol::Response>
@@ -272,6 +303,23 @@ RendererOverridesHandler::GrantPermissionsForSetFileInputFiles(
}
+// Network agent handlers ----------------------------------------------------
+
+scoped_refptr<DevToolsProtocol::Response>
+RendererOverridesHandler::ClearBrowserCache(
+ scoped_refptr<DevToolsProtocol::Command> command) {
+ GetContentClient()->browser()->ClearCache(agent_->GetRenderViewHost());
+ return command->SuccessResponse(NULL);
+}
+
+scoped_refptr<DevToolsProtocol::Response>
+RendererOverridesHandler::ClearBrowserCookies(
+ scoped_refptr<DevToolsProtocol::Command> command) {
+ GetContentClient()->browser()->ClearCookies(agent_->GetRenderViewHost());
+ return command->SuccessResponse(NULL);
+}
+
+
// Page agent handlers -------------------------------------------------------
scoped_refptr<DevToolsProtocol::Response>
@@ -306,7 +354,7 @@ RendererOverridesHandler::PageHandleJavaScriptDialog(
web_contents->GetDelegate()->GetJavaScriptDialogManager();
if (manager && manager->HandleJavaScriptDialog(
web_contents, accept, prompt_override_ptr)) {
- return NULL;
+ return command->SuccessResponse(new base::DictionaryValue());
}
}
}
@@ -367,7 +415,7 @@ RendererOverridesHandler::PageGetNavigationHistory(
result->SetInteger(
devtools::Page::getNavigationHistory::kResponseCurrentIndex,
controller.GetCurrentEntryIndex());
- ListValue* entries = new ListValue();
+ base::ListValue* entries = new base::ListValue();
for (int i = 0; i != controller.GetEntryCount(); ++i) {
const NavigationEntry* entry = controller.GetEntryAtIndex(i);
base::DictionaryValue* entry_value = new base::DictionaryValue();
@@ -426,44 +474,41 @@ RendererOverridesHandler::PageCaptureScreenshot(
if (!host->GetView())
return command->InternalErrorResponse("Unable to access the view");
- std::string format;
- int quality = kDefaultScreenshotQuality;
- double scale = 1;
- ParseCaptureParameters(command.get(), &format, &quality, &scale);
-
gfx::Rect view_bounds = host->GetView()->GetViewBounds();
- gfx::Size snapshot_size = gfx::ToFlooredSize(
- gfx::ScaleSize(view_bounds.size(), scale));
-
- // Grab screen pixels if available for current platform.
- // TODO(pfeldman): support format, scale and quality in ui::GrabViewSnapshot.
- std::vector<unsigned char> png;
- bool is_unscaled_png = scale == 1 && format == kPng;
- if (is_unscaled_png && ui::GrabViewSnapshot(host->GetView()->GetNativeView(),
- &png,
- gfx::Rect(snapshot_size))) {
- std::string base64_data;
- base::Base64Encode(
- base::StringPiece(reinterpret_cast<char*>(&*png.begin()), png.size()),
- &base64_data);
- base::DictionaryValue* result = new base::DictionaryValue();
- result->SetString(
- devtools::Page::captureScreenshot::kResponseData, base64_data);
- return command->SuccessResponse(result);
+ gfx::Rect snapshot_bounds(view_bounds.size());
+ gfx::Size snapshot_size = snapshot_bounds.size();
+
+ std::vector<unsigned char> png_data;
+ if (ui::GrabViewSnapshot(host->GetView()->GetNativeView(),
+ &png_data,
+ snapshot_bounds)) {
+ if (png_data.size())
+ return command->SuccessResponse(CreateScreenshotResponse(png_data));
+ else
+ return command->InternalErrorResponse("Unable to capture screenshot");
}
- // Fallback to copying from compositing surface.
- RenderWidgetHostViewPort* view_port =
- RenderWidgetHostViewPort::FromRWHV(host->GetView());
-
- view_port->CopyFromCompositingSurface(
- view_bounds, snapshot_size,
+ ui::GrabViewSnapshotAsync(
+ host->GetView()->GetNativeView(),
+ snapshot_bounds,
+ base::ThreadTaskRunnerHandle::Get(),
base::Bind(&RendererOverridesHandler::ScreenshotCaptured,
- weak_factory_.GetWeakPtr(), command, format, quality,
- last_compositor_frame_metadata_));
+ weak_factory_.GetWeakPtr(), command));
return command->AsyncResponsePromise();
}
+void RendererOverridesHandler::ScreenshotCaptured(
+ scoped_refptr<DevToolsProtocol::Command> command,
+ scoped_refptr<base::RefCountedBytes> png_data) {
+ if (png_data) {
+ SendAsyncResponse(
+ command->SuccessResponse(CreateScreenshotResponse(png_data->data())));
+ } else {
+ SendAsyncResponse(
+ command->InternalErrorResponse("Unable to capture screenshot"));
+ }
+}
+
scoped_refptr<DevToolsProtocol::Response>
RendererOverridesHandler::PageCanScreencast(
scoped_refptr<DevToolsProtocol::Command> command) {
@@ -497,18 +542,14 @@ RendererOverridesHandler::PageStopScreencast(
return command->SuccessResponse(NULL);
}
-void RendererOverridesHandler::ScreenshotCaptured(
- scoped_refptr<DevToolsProtocol::Command> command,
+void RendererOverridesHandler::ScreencastFrameCaptured(
const std::string& format,
int quality,
const cc::CompositorFrameMetadata& metadata,
bool success,
const SkBitmap& bitmap) {
if (!success) {
- if (command) {
- SendAsyncResponse(
- command->InternalErrorResponse("Unable to capture screenshot"));
- } else if (capture_retry_count_) {
+ if (capture_retry_count_) {
--capture_retry_count_;
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
@@ -541,13 +582,8 @@ void RendererOverridesHandler::ScreenshotCaptured(
encoded = false;
}
- if (!encoded) {
- if (command) {
- SendAsyncResponse(
- command->InternalErrorResponse("Unable to encode screenshot"));
- }
+ if (!encoded)
return;
- }
std::string base_64_data;
base::Base64Encode(
@@ -593,20 +629,11 @@ void RendererOverridesHandler::ScreenshotCaptured(
response_metadata->Set(
devtools::Page::ScreencastFrameMetadata::kParamViewport, viewport);
- if (command) {
- response->Set(devtools::Page::captureScreenshot::kResponseMetadata,
- response_metadata);
- } else {
- response->Set(devtools::Page::screencastFrame::kParamMetadata,
- response_metadata);
- }
+ response->Set(devtools::Page::screencastFrame::kParamMetadata,
+ response_metadata);
}
- if (command) {
- SendAsyncResponse(command->SuccessResponse(response));
- } else {
- SendNotification(devtools::Page::screencastFrame::kName, response);
- }
+ SendNotification(devtools::Page::screencastFrame::kName, response);
}
// Quota and Usage ------------------------------------------
@@ -906,6 +933,7 @@ RendererOverridesHandler::InputDispatchGestureEvent(
agent_->GetRenderViewHost());
blink::WebGestureEvent event;
ParseGenericInputParams(params, &event);
+ event.sourceDevice = blink::WebGestureDeviceTouchscreen;
std::string type;
if (params->GetString(devtools::Input::dispatchGestureEvent::kParamType,
diff --git a/chromium/content/browser/devtools/renderer_overrides_handler.h b/chromium/content/browser/devtools/renderer_overrides_handler.h
index cce32767c39..0f7f8bc6cba 100644
--- a/chromium/content/browser/devtools/renderer_overrides_handler.h
+++ b/chromium/content/browser/devtools/renderer_overrides_handler.h
@@ -7,6 +7,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/memory/ref_counted_memory.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
@@ -43,12 +44,20 @@ class CONTENT_EXPORT RendererOverridesHandler
void ParseCaptureParameters(DevToolsProtocol::Command* command,
std::string* format, int* quality,
double* scale);
+ base::DictionaryValue* CreateScreenshotResponse(
+ const std::vector<unsigned char>& png_data);
// DOM domain.
scoped_refptr<DevToolsProtocol::Response>
GrantPermissionsForSetFileInputFiles(
scoped_refptr<DevToolsProtocol::Command> command);
+ // Network domain.
+ scoped_refptr<DevToolsProtocol::Response> ClearBrowserCache(
+ scoped_refptr<DevToolsProtocol::Command> command);
+ scoped_refptr<DevToolsProtocol::Response> ClearBrowserCookies(
+ scoped_refptr<DevToolsProtocol::Command> command);
+
// Page domain.
scoped_refptr<DevToolsProtocol::Response> PageDisable(
scoped_refptr<DevToolsProtocol::Command> command);
@@ -75,6 +84,9 @@ class CONTENT_EXPORT RendererOverridesHandler
void ScreenshotCaptured(
scoped_refptr<DevToolsProtocol::Command> command,
+ scoped_refptr<base::RefCountedBytes> png_data);
+
+ void ScreencastFrameCaptured(
const std::string& format,
int quality,
const cc::CompositorFrameMetadata& metadata,
diff --git a/chromium/content/browser/devtools/renderer_overrides_handler_browsertest.cc b/chromium/content/browser/devtools/renderer_overrides_handler_browsertest.cc
index 24dd9621341..d869d9d6e6c 100644
--- a/chromium/content/browser/devtools/renderer_overrides_handler_browsertest.cc
+++ b/chromium/content/browser/devtools/renderer_overrides_handler_browsertest.cc
@@ -8,9 +8,9 @@
#include "content/browser/devtools/renderer_overrides_handler.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
-#include "content/test/content_browser_test.h"
-#include "content/test/content_browser_test_utils.h"
namespace content {
@@ -18,14 +18,15 @@ class RendererOverridesHandlerTest : public ContentBrowserTest {
protected:
scoped_refptr<DevToolsProtocol::Response> SendCommand(
const std::string& method,
- DictionaryValue* params) {
+ base::DictionaryValue* params) {
scoped_ptr<RendererOverridesHandler> handler(CreateHandler());
scoped_refptr<DevToolsProtocol::Command> command(
DevToolsProtocol::CreateCommand(1, method, params));
return handler->HandleCommand(command);
}
- void SendAsyncCommand(const std::string& method, DictionaryValue* params) {
+ void SendAsyncCommand(const std::string& method,
+ base::DictionaryValue* params) {
scoped_ptr<RendererOverridesHandler> handler(CreateHandler());
scoped_refptr<DevToolsProtocol::Command> command(
DevToolsProtocol::CreateCommand(1, method, params));
@@ -84,7 +85,7 @@ class RendererOverridesHandlerTest : public ContentBrowserTest {
};
IN_PROC_BROWSER_TEST_F(RendererOverridesHandlerTest, QueryUsageAndQuota) {
- DictionaryValue* params = new DictionaryValue();
+ base::DictionaryValue* params = new base::DictionaryValue();
params->SetString("securityOrigin", "http://example.com");
SendAsyncCommand("Page.queryUsageAndQuota", params);
diff --git a/chromium/content/browser/devtools/tethering_handler.cc b/chromium/content/browser/devtools/tethering_handler.cc
index d3e787d0c01..9b3b7fa005a 100644
--- a/chromium/content/browser/devtools/tethering_handler.cc
+++ b/chromium/content/browser/devtools/tethering_handler.cc
@@ -149,7 +149,7 @@ class SocketPump : public net::StreamListenSocket::Delegate {
}
void SelfDestruct() {
- if (wire_buffer_->offset() != wire_buffer_size_) {
+ if (wire_buffer_ && wire_buffer_->offset() != wire_buffer_size_) {
pending_destruction_ = true;
return;
}
diff --git a/chromium/content/browser/devtools/worker_devtools_manager.cc b/chromium/content/browser/devtools/worker_devtools_manager.cc
index f0608815f33..0658c353c64 100644
--- a/chromium/content/browser/devtools/worker_devtools_manager.cc
+++ b/chromium/content/browser/devtools/worker_devtools_manager.cc
@@ -12,6 +12,7 @@
#include "content/browser/devtools/devtools_manager_impl.h"
#include "content/browser/devtools/devtools_protocol.h"
#include "content/browser/devtools/devtools_protocol_constants.h"
+#include "content/browser/devtools/embedded_worker_devtools_manager.h"
#include "content/browser/devtools/ipc_devtools_agent_host.h"
#include "content/browser/devtools/worker_devtools_message_filter.h"
#include "content/browser/worker_host/worker_service_impl.h"
@@ -27,19 +28,13 @@ namespace content {
scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::GetForWorker(
int worker_process_id,
int worker_route_id) {
- return WorkerDevToolsManager::GetDevToolsAgentHostForWorker(
- worker_process_id,
- worker_route_id);
-}
-
-// Called on the UI thread.
-// static
-bool DevToolsAgentHost::HasForWorker(
- int worker_process_id,
- int worker_route_id) {
- return WorkerDevToolsManager::HasDevToolsAgentHostForWorker(
- worker_process_id,
- worker_route_id);
+ if (WorkerService::EmbeddedSharedWorkerEnabled()) {
+ return EmbeddedWorkerDevToolsManager::GetInstance()
+ ->GetDevToolsAgentHostForWorker(worker_process_id, worker_route_id);
+ } else {
+ return WorkerDevToolsManager::GetDevToolsAgentHostForWorker(
+ worker_process_id, worker_route_id);
+ }
}
namespace {
@@ -217,6 +212,7 @@ struct WorkerDevToolsManager::InspectedWorker {
// static
WorkerDevToolsManager* WorkerDevToolsManager::GetInstance() {
+ DCHECK(!WorkerService::EmbeddedSharedWorkerEnabled());
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
return Singleton<WorkerDevToolsManager>::get();
}
@@ -225,6 +221,7 @@ WorkerDevToolsManager* WorkerDevToolsManager::GetInstance() {
DevToolsAgentHost* WorkerDevToolsManager::GetDevToolsAgentHostForWorker(
int worker_process_id,
int worker_route_id) {
+ DCHECK(!WorkerService::EmbeddedSharedWorkerEnabled());
WorkerId id(worker_process_id, worker_route_id);
AgentHosts::iterator it = g_agent_map.Get().find(id);
if (it == g_agent_map.Get().end())
@@ -232,21 +229,13 @@ DevToolsAgentHost* WorkerDevToolsManager::GetDevToolsAgentHostForWorker(
return it->second;
}
-// static
-bool WorkerDevToolsManager::HasDevToolsAgentHostForWorker(
- int worker_process_id,
- int worker_route_id) {
- WorkerId id(worker_process_id, worker_route_id);
- return g_agent_map.Get().find(id) != g_agent_map.Get().end();
-}
-
WorkerDevToolsManager::WorkerDevToolsManager() {
}
WorkerDevToolsManager::~WorkerDevToolsManager() {
}
-void WorkerDevToolsManager::WorkerCreated(
+bool WorkerDevToolsManager::WorkerCreated(
WorkerProcessHost* worker,
const WorkerProcessHost::WorkerInstance& instance) {
for (TerminatedInspectedWorkers::iterator it = terminated_workers_.begin();
@@ -254,14 +243,13 @@ void WorkerDevToolsManager::WorkerCreated(
if (instance.Matches(it->worker_url, it->worker_name,
instance.partition(),
instance.resource_context())) {
- worker->Send(new DevToolsAgentMsg_PauseWorkerContextOnStart(
- instance.worker_route_id()));
WorkerId new_worker_id(worker->GetData().id, instance.worker_route_id());
paused_workers_[new_worker_id] = it->old_worker_id;
terminated_workers_.erase(it);
- return;
+ return true;
}
}
+ return false;
}
void WorkerDevToolsManager::WorkerDestroyed(
diff --git a/chromium/content/browser/devtools/worker_devtools_manager.h b/chromium/content/browser/devtools/worker_devtools_manager.h
index 8a9a7084226..73916c30fe2 100644
--- a/chromium/content/browser/devtools/worker_devtools_manager.h
+++ b/chromium/content/browser/devtools/worker_devtools_manager.h
@@ -19,6 +19,7 @@ namespace content {
class DevToolsAgentHost;
// All methods are supposed to be called on the IO thread.
+// This class is not used when "enable-embedded-shared-worker" flag is set.
class WorkerDevToolsManager {
public:
typedef std::pair<int, int> WorkerId;
@@ -32,11 +33,6 @@ class WorkerDevToolsManager {
int worker_process_id,
int worker_route_id);
- // Called on the UI thread.
- static bool HasDevToolsAgentHostForWorker(
- int worker_process_id,
- int worker_route_id);
-
void ForwardToDevToolsClient(int worker_process_id,
int worker_route_id,
const std::string& message);
@@ -45,9 +41,9 @@ class WorkerDevToolsManager {
const std::string& state);
// Called on the IO thread.
- void WorkerCreated(
- WorkerProcessHost* process,
- const WorkerProcessHost::WorkerInstance& instance);
+ // Returns true when the worker must be paused on start.
+ bool WorkerCreated(WorkerProcessHost* process,
+ const WorkerProcessHost::WorkerInstance& instance);
void WorkerDestroyed(WorkerProcessHost* process, int worker_route_id);
void WorkerContextStarted(WorkerProcessHost* process, int worker_route_id);
diff --git a/chromium/content/browser/devtools/worker_devtools_message_filter.cc b/chromium/content/browser/devtools/worker_devtools_message_filter.cc
index 3f5553f120c..23c068b5405 100644
--- a/chromium/content/browser/devtools/worker_devtools_message_filter.cc
+++ b/chromium/content/browser/devtools/worker_devtools_message_filter.cc
@@ -12,7 +12,8 @@ namespace content {
WorkerDevToolsMessageFilter::WorkerDevToolsMessageFilter(
int worker_process_host_id)
- : worker_process_host_id_(worker_process_host_id),
+ : BrowserMessageFilter(DevToolsMsgStart),
+ worker_process_host_id_(worker_process_host_id),
current_routing_id_(0) {
}
@@ -20,18 +21,16 @@ WorkerDevToolsMessageFilter::~WorkerDevToolsMessageFilter() {
}
bool WorkerDevToolsMessageFilter::OnMessageReceived(
- const IPC::Message& message,
- bool* message_was_ok) {
+ const IPC::Message& message) {
bool handled = true;
current_routing_id_ = message.routing_id();
- IPC_BEGIN_MESSAGE_MAP_EX(WorkerDevToolsMessageFilter, message,
- *message_was_ok)
+ IPC_BEGIN_MESSAGE_MAP(WorkerDevToolsMessageFilter, message)
IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend,
OnDispatchOnInspectorFrontend)
IPC_MESSAGE_HANDLER(DevToolsHostMsg_SaveAgentRuntimeState,
OnSaveAgentRumtimeState)
IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP_EX()
+ IPC_END_MESSAGE_MAP()
return handled;
}
diff --git a/chromium/content/browser/devtools/worker_devtools_message_filter.h b/chromium/content/browser/devtools/worker_devtools_message_filter.h
index 73ba6f8442a..c80658e8dbf 100644
--- a/chromium/content/browser/devtools/worker_devtools_message_filter.h
+++ b/chromium/content/browser/devtools/worker_devtools_message_filter.h
@@ -18,8 +18,7 @@ class WorkerDevToolsMessageFilter : public BrowserMessageFilter {
virtual ~WorkerDevToolsMessageFilter();
// BrowserMessageFilter implementation.
- virtual bool OnMessageReceived(const IPC::Message& message,
- bool* message_was_ok) OVERRIDE;
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
// Message handlers.
void OnDispatchOnInspectorFrontend(const std::string& message);
void OnSaveAgentRumtimeState(const std::string& state);