Blink roll 25b6bd3a7a131ffe68d809546ad1a20707915cdc:3a503f41ae42e5b79cfcd2ff10e65afde...
[chromium-blink-merge.git] / content / browser / devtools / embedded_worker_devtools_agent_host.cc
blob54766f808274855688d425e103c087706946d51c
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/devtools/embedded_worker_devtools_agent_host.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "content/browser/devtools/protocol/devtools_protocol_handler_impl.h"
9 #include "content/browser/service_worker/service_worker_context_core.h"
10 #include "content/browser/service_worker/service_worker_version.h"
11 #include "content/browser/shared_worker/shared_worker_service_impl.h"
12 #include "content/common/devtools_messages.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/render_process_host.h"
16 namespace content {
18 namespace {
20 void TerminateSharedWorkerOnIO(
21 EmbeddedWorkerDevToolsAgentHost::WorkerId worker_id) {
22 SharedWorkerServiceImpl::GetInstance()->TerminateWorker(
23 worker_id.first, worker_id.second);
26 void StatusNoOp(ServiceWorkerStatusCode status) {
29 void TerminateServiceWorkerOnIO(
30 base::WeakPtr<ServiceWorkerContextCore> context_weak,
31 int64 version_id) {
32 if (ServiceWorkerContextCore* context = context_weak.get()) {
33 if (ServiceWorkerVersion* version = context->GetLiveVersion(version_id))
34 version->StopWorker(base::Bind(&StatusNoOp));
40 EmbeddedWorkerDevToolsAgentHost::EmbeddedWorkerDevToolsAgentHost(
41 WorkerId worker_id,
42 const SharedWorkerInstance& shared_worker)
43 : shared_worker_(new SharedWorkerInstance(shared_worker)),
44 state_(WORKER_UNINSPECTED),
45 worker_id_(worker_id) {
46 WorkerCreated();
49 EmbeddedWorkerDevToolsAgentHost::EmbeddedWorkerDevToolsAgentHost(
50 WorkerId worker_id,
51 const ServiceWorkerIdentifier& service_worker,
52 bool debug_service_worker_on_start)
53 : service_worker_(new ServiceWorkerIdentifier(service_worker)),
54 state_(WORKER_UNINSPECTED),
55 worker_id_(worker_id) {
56 if (debug_service_worker_on_start)
57 state_ = WORKER_PAUSED_FOR_DEBUG_ON_START;
58 WorkerCreated();
61 bool EmbeddedWorkerDevToolsAgentHost::IsWorker() const {
62 return true;
65 DevToolsAgentHost::Type EmbeddedWorkerDevToolsAgentHost::GetType() {
66 return shared_worker_ ? TYPE_SHARED_WORKER : TYPE_SERVICE_WORKER;
69 std::string EmbeddedWorkerDevToolsAgentHost::GetTitle() {
70 if (shared_worker_ && shared_worker_->name().length())
71 return base::UTF16ToUTF8(shared_worker_->name());
72 if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first)) {
73 return base::StringPrintf("Worker pid:%d",
74 base::GetProcId(host->GetHandle()));
76 return "";
79 GURL EmbeddedWorkerDevToolsAgentHost::GetURL() {
80 if (shared_worker_)
81 return shared_worker_->url();
82 if (service_worker_)
83 return service_worker_->url();
84 return GURL();
87 bool EmbeddedWorkerDevToolsAgentHost::Activate() {
88 return false;
91 bool EmbeddedWorkerDevToolsAgentHost::Close() {
92 if (shared_worker_) {
93 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
94 base::Bind(&TerminateSharedWorkerOnIO, worker_id_));
95 return true;
97 if (service_worker_) {
98 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
99 base::Bind(&TerminateServiceWorkerOnIO,
100 service_worker_->context_weak(),
101 service_worker_->version_id()));
102 return true;
104 return false;
107 void EmbeddedWorkerDevToolsAgentHost::SendMessageToAgent(
108 IPC::Message* message_raw) {
109 scoped_ptr<IPC::Message> message(message_raw);
110 if (state_ != WORKER_INSPECTED)
111 return;
112 if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first)) {
113 message->set_routing_id(worker_id_.second);
114 host->Send(message.release());
118 void EmbeddedWorkerDevToolsAgentHost::Attach() {
119 if (state_ != WORKER_INSPECTED) {
120 state_ = WORKER_INSPECTED;
121 AttachToWorker();
123 IPCDevToolsAgentHost::Attach();
126 void EmbeddedWorkerDevToolsAgentHost::OnClientAttached() {
127 DevToolsAgentHostImpl::NotifyCallbacks(this, true);
130 void EmbeddedWorkerDevToolsAgentHost::OnClientDetached() {
131 if (state_ == WORKER_INSPECTED) {
132 state_ = WORKER_UNINSPECTED;
133 DetachFromWorker();
134 } else if (state_ == WORKER_PAUSED_FOR_REATTACH) {
135 state_ = WORKER_UNINSPECTED;
137 DevToolsAgentHostImpl::NotifyCallbacks(this, false);
140 bool EmbeddedWorkerDevToolsAgentHost::OnMessageReceived(
141 const IPC::Message& msg) {
142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
143 bool handled = true;
144 IPC_BEGIN_MESSAGE_MAP(EmbeddedWorkerDevToolsAgentHost, msg)
145 IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend,
146 OnDispatchOnInspectorFrontend)
147 IPC_MESSAGE_HANDLER(DevToolsHostMsg_SaveAgentRuntimeState,
148 OnSaveAgentRuntimeState)
149 IPC_MESSAGE_UNHANDLED(handled = false)
150 IPC_END_MESSAGE_MAP()
151 return handled;
154 void EmbeddedWorkerDevToolsAgentHost::WorkerReadyForInspection() {
155 if (state_ == WORKER_PAUSED_FOR_DEBUG_ON_START) {
156 RenderProcessHost* rph = RenderProcessHost::FromID(worker_id_.first);
157 Inspect(rph->GetBrowserContext());
158 } else if (state_ == WORKER_PAUSED_FOR_REATTACH) {
159 DCHECK(IsAttached());
160 state_ = WORKER_INSPECTED;
161 AttachToWorker();
162 Reattach(saved_agent_state_);
166 void EmbeddedWorkerDevToolsAgentHost::WorkerRestarted(WorkerId worker_id) {
167 DCHECK_EQ(WORKER_TERMINATED, state_);
168 state_ = IsAttached() ? WORKER_PAUSED_FOR_REATTACH : WORKER_UNINSPECTED;
169 worker_id_ = worker_id;
170 WorkerCreated();
173 void EmbeddedWorkerDevToolsAgentHost::WorkerDestroyed() {
174 DCHECK_NE(WORKER_TERMINATED, state_);
175 if (state_ == WORKER_INSPECTED) {
176 DCHECK(IsAttached());
177 // Client host is debugging this worker agent host.
178 base::Callback<void(const std::string&)> raw_message_callback(
179 base::Bind(&EmbeddedWorkerDevToolsAgentHost::SendMessageToClient,
180 base::Unretained(this)));
181 devtools::worker::Client worker(raw_message_callback);
182 worker.DisconnectedFromWorker(
183 devtools::worker::DisconnectedFromWorkerParams::Create());
184 DetachFromWorker();
186 state_ = WORKER_TERMINATED;
187 Release(); // Balanced in WorkerCreated()
190 bool EmbeddedWorkerDevToolsAgentHost::Matches(
191 const SharedWorkerInstance& other) {
192 return shared_worker_ && shared_worker_->Matches(other);
195 bool EmbeddedWorkerDevToolsAgentHost::Matches(
196 const ServiceWorkerIdentifier& other) {
197 return service_worker_ && service_worker_->Matches(other);
200 bool EmbeddedWorkerDevToolsAgentHost::IsTerminated() {
201 return state_ == WORKER_TERMINATED;
204 EmbeddedWorkerDevToolsAgentHost::~EmbeddedWorkerDevToolsAgentHost() {
205 DCHECK_EQ(WORKER_TERMINATED, state_);
206 EmbeddedWorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(
207 worker_id_);
210 void EmbeddedWorkerDevToolsAgentHost::AttachToWorker() {
211 if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
212 host->AddRoute(worker_id_.second, this);
215 void EmbeddedWorkerDevToolsAgentHost::DetachFromWorker() {
216 if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
217 host->RemoveRoute(worker_id_.second);
220 void EmbeddedWorkerDevToolsAgentHost::WorkerCreated() {
221 AddRef(); // Balanced in WorkerDestroyed()
224 void EmbeddedWorkerDevToolsAgentHost::OnDispatchOnInspectorFrontend(
225 const std::string& message,
226 uint32 total_size) {
227 if (!IsAttached())
228 return;
230 ProcessChunkedMessageFromAgent(message, total_size);
233 BrowserContext* EmbeddedWorkerDevToolsAgentHost::GetBrowserContext() {
234 RenderProcessHost* rph = RenderProcessHost::FromID(worker_id_.first);
235 return rph ? rph->GetBrowserContext() : nullptr;
238 void EmbeddedWorkerDevToolsAgentHost::OnSaveAgentRuntimeState(
239 const std::string& state) {
240 saved_agent_state_ = state;
243 } // namespace content