Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: content/browser/devtools/embedded_worker_devtools_manager.cc

Issue 299693002: Add option to open the DevTools window for ServiceWorker on start in serviceworker-internals. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/devtools/embedded_worker_devtools_manager.h" 5 #include "content/browser/devtools/embedded_worker_devtools_manager.h"
6 6
7 #include "content/browser/devtools/devtools_manager_impl.h" 7 #include "content/browser/devtools/devtools_manager_impl.h"
8 #include "content/browser/devtools/devtools_protocol.h" 8 #include "content/browser/devtools/devtools_protocol.h"
9 #include "content/browser/devtools/devtools_protocol_constants.h" 9 #include "content/browser/devtools/devtools_protocol_constants.h"
10 #include "content/browser/devtools/ipc_devtools_agent_host.h" 10 #include "content/browser/devtools/ipc_devtools_agent_host.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 49
50 bool EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::Matches( 50 bool EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::Matches(
51 const ServiceWorkerIdentifier& other) const { 51 const ServiceWorkerIdentifier& other) const {
52 return service_worker_context_ == other.service_worker_context_ && 52 return service_worker_context_ == other.service_worker_context_ &&
53 service_worker_version_id_ == other.service_worker_version_id_; 53 service_worker_version_id_ == other.service_worker_version_id_;
54 } 54 }
55 55
56 EmbeddedWorkerDevToolsManager::WorkerInfo::WorkerInfo( 56 EmbeddedWorkerDevToolsManager::WorkerInfo::WorkerInfo(
57 const SharedWorkerInstance& instance) 57 const SharedWorkerInstance& instance)
58 : shared_worker_instance_(new SharedWorkerInstance(instance)), 58 : shared_worker_instance_(new SharedWorkerInstance(instance)),
59 debug_on_start_(false),
59 state_(WORKER_UNINSPECTED), 60 state_(WORKER_UNINSPECTED),
60 agent_host_(NULL) { 61 agent_host_(NULL) {
61 } 62 }
62 63
63 EmbeddedWorkerDevToolsManager::WorkerInfo::WorkerInfo( 64 EmbeddedWorkerDevToolsManager::WorkerInfo::WorkerInfo(
64 const ServiceWorkerIdentifier& service_worker_id) 65 const ServiceWorkerIdentifier& service_worker_id,
66 bool debug_on_start)
65 : service_worker_id_(new ServiceWorkerIdentifier(service_worker_id)), 67 : service_worker_id_(new ServiceWorkerIdentifier(service_worker_id)),
68 debug_on_start_(debug_on_start),
66 state_(WORKER_UNINSPECTED), 69 state_(WORKER_UNINSPECTED),
67 agent_host_(NULL) { 70 agent_host_(NULL) {
68 } 71 }
69 72
70 bool EmbeddedWorkerDevToolsManager::WorkerInfo::Matches( 73 bool EmbeddedWorkerDevToolsManager::WorkerInfo::Matches(
71 const SharedWorkerInstance& other) { 74 const SharedWorkerInstance& other) {
72 if (!shared_worker_instance_) 75 if (!shared_worker_instance_)
73 return false; 76 return false;
74 return shared_worker_instance_->Matches(other); 77 return shared_worker_instance_->Matches(other);
75 } 78 }
76 79
77 bool EmbeddedWorkerDevToolsManager::WorkerInfo::Matches( 80 bool EmbeddedWorkerDevToolsManager::WorkerInfo::Matches(
78 const ServiceWorkerIdentifier& other) { 81 const ServiceWorkerIdentifier& other) {
79 if (!service_worker_id_) 82 if (!service_worker_id_)
80 return false; 83 return false;
81 return service_worker_id_->Matches(other); 84 return service_worker_id_->Matches(other);
82 } 85 }
83 86
84 EmbeddedWorkerDevToolsManager::WorkerInfo::~WorkerInfo() { 87 EmbeddedWorkerDevToolsManager::WorkerInfo::~WorkerInfo() {
85 } 88 }
86 89
87 class EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsAgentHost 90 class EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsAgentHost
88 : public IPCDevToolsAgentHost, 91 : public IPCDevToolsAgentHost,
89 public IPC::Listener { 92 public IPC::Listener {
90 public: 93 public:
91 explicit EmbeddedWorkerDevToolsAgentHost(WorkerId worker_id) 94 explicit EmbeddedWorkerDevToolsAgentHost(WorkerId worker_id,
92 : worker_id_(worker_id), worker_attached_(true) { 95 bool debug_on_start)
96 : worker_id_(worker_id),
97 worker_attached_(true),
98 paused_for_debug_on_start_(debug_on_start) {
93 AddRef(); 99 AddRef();
94 if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first)) 100 if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
95 host->AddRoute(worker_id_.second, this); 101 host->AddRoute(worker_id_.second, this);
96 } 102 }
97 103
98 // DevToolsAgentHost override. 104 // DevToolsAgentHost override.
99 virtual bool IsWorker() const OVERRIDE { return true; } 105 virtual bool IsWorker() const OVERRIDE { return true; }
106 virtual bool IsWorkerPaused() const OVERRIDE {
107 // If IsWorkerPaused returns true, DevTools window will be opend with
108 // "workerPaused" option. And the script execution of ServiceWorker will be
109 // resumed and then paused on the first script statement. This is done by
110 // calling Debugger.pause and Runtime.run from the DevTools front end.
111 return paused_for_debug_on_start_;
112 }
100 113
101 // IPCDevToolsAgentHost implementation. 114 // IPCDevToolsAgentHost implementation.
102 virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE { 115 virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE {
116 if (paused_for_debug_on_start_ &&
117 message->type() == DevToolsAgentMsg_DispatchOnInspectorBackend::ID) {
118 // This is a bit tricky but we have to clear |paused_for_debug_on_start_|
119 // when "Runtime.run" is called from the DevTools front end. Otherwise
120 // when the user reopens the DevTools later the SharedWorker will be
121 // paused because the DevTools front end will call Debugger.pause and
122 // Runtime.run again.
123 DevToolsAgentMsg_DispatchOnInspectorBackend::Param params;
124 if (DevToolsAgentMsg_DispatchOnInspectorBackend::Read(message, &params) &&
125 params.a.find("Runtime.run") != std::string::npos) {
126 paused_for_debug_on_start_ = false;
127 }
128 }
129
103 if (worker_attached_) 130 if (worker_attached_)
104 SendMessageToWorker(worker_id_, message); 131 SendMessageToWorker(worker_id_, message);
105 else 132 else
106 delete message; 133 delete message;
107 } 134 }
108 virtual void OnClientAttached() OVERRIDE {} 135 virtual void OnClientAttached() OVERRIDE {}
109 virtual void OnClientDetached() OVERRIDE {} 136 virtual void OnClientDetached() OVERRIDE {}
110 137
111 // IPC::Listener implementation. 138 // IPC::Listener implementation.
112 virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE { 139 virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 178
152 void OnDispatchOnInspectorFrontend(const std::string& message) { 179 void OnDispatchOnInspectorFrontend(const std::string& message) {
153 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(this, 180 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(this,
154 message); 181 message);
155 } 182 }
156 183
157 void OnSaveAgentRuntimeState(const std::string& state) { state_ = state; } 184 void OnSaveAgentRuntimeState(const std::string& state) { state_ = state; }
158 185
159 WorkerId worker_id_; 186 WorkerId worker_id_;
160 bool worker_attached_; 187 bool worker_attached_;
188 bool paused_for_debug_on_start_;
161 std::string state_; 189 std::string state_;
162 DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerDevToolsAgentHost); 190 DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerDevToolsAgentHost);
163 }; 191 };
164 192
165 // static 193 // static
166 EmbeddedWorkerDevToolsManager* EmbeddedWorkerDevToolsManager::GetInstance() { 194 EmbeddedWorkerDevToolsManager* EmbeddedWorkerDevToolsManager::GetInstance() {
167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
168 return Singleton<EmbeddedWorkerDevToolsManager>::get(); 196 return Singleton<EmbeddedWorkerDevToolsManager>::get();
169 } 197 }
170 198
171 DevToolsAgentHost* EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForWorker( 199 DevToolsAgentHost* EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForWorker(
172 int worker_process_id, 200 int worker_process_id,
173 int worker_route_id) { 201 int worker_route_id) {
174 WorkerId id(worker_process_id, worker_route_id); 202 WorkerId id(worker_process_id, worker_route_id);
175 203
176 WorkerInfoMap::iterator it = workers_.find(id); 204 WorkerInfoMap::iterator it = workers_.find(id);
177 if (it == workers_.end()) 205 if (it == workers_.end())
178 return NULL; 206 return NULL;
179 207
180 WorkerInfo* info = it->second; 208 WorkerInfo* info = it->second;
181 if (info->state() != WORKER_UNINSPECTED) 209 if (info->state() != WORKER_UNINSPECTED)
182 return info->agent_host(); 210 return info->agent_host();
183 211
184 EmbeddedWorkerDevToolsAgentHost* agent_host = 212 EmbeddedWorkerDevToolsAgentHost* agent_host =
185 new EmbeddedWorkerDevToolsAgentHost(id); 213 new EmbeddedWorkerDevToolsAgentHost(id, info->debug_on_start());
186 info->set_agent_host(agent_host); 214 info->set_agent_host(agent_host);
187 info->set_state(WORKER_INSPECTED); 215 info->set_state(WORKER_INSPECTED);
188 return agent_host; 216 return agent_host;
189 } 217 }
190 218
191 DevToolsAgentHost* 219 DevToolsAgentHost*
192 EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForServiceWorker( 220 EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForServiceWorker(
193 const ServiceWorkerIdentifier& service_worker_id) { 221 const ServiceWorkerIdentifier& service_worker_id) {
194 WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(service_worker_id); 222 WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(service_worker_id);
195 if (it == workers_.end()) 223 if (it == workers_.end())
196 return NULL; 224 return NULL;
197 return GetDevToolsAgentHostForWorker(it->first.first, it->first.second); 225 return GetDevToolsAgentHostForWorker(it->first.first, it->first.second);
198 } 226 }
199 227
200 EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsManager() { 228 EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsManager()
229 : debug_service_worker_on_start_(false) {
201 } 230 }
202 231
203 EmbeddedWorkerDevToolsManager::~EmbeddedWorkerDevToolsManager() { 232 EmbeddedWorkerDevToolsManager::~EmbeddedWorkerDevToolsManager() {
204 } 233 }
205 234
206 bool EmbeddedWorkerDevToolsManager::SharedWorkerCreated( 235 bool EmbeddedWorkerDevToolsManager::SharedWorkerCreated(
207 int worker_process_id, 236 int worker_process_id,
208 int worker_route_id, 237 int worker_route_id,
209 const SharedWorkerInstance& instance) { 238 const SharedWorkerInstance& instance) {
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
211 const WorkerId id(worker_process_id, worker_route_id); 240 const WorkerId id(worker_process_id, worker_route_id);
212 WorkerInfoMap::iterator it = FindExistingSharedWorkerInfo(instance); 241 WorkerInfoMap::iterator it = FindExistingSharedWorkerInfo(instance);
213 if (it == workers_.end()) { 242 if (it == workers_.end()) {
214 scoped_ptr<WorkerInfo> info(new WorkerInfo(instance)); 243 scoped_ptr<WorkerInfo> info(new WorkerInfo(instance));
215 workers_.set(id, info.Pass()); 244 workers_.set(id, info.Pass());
216 return false; 245 return false;
217 } 246 }
218 MoveToPausedState(id, it); 247 MoveToPausedState(id, it);
219 return true; 248 return true;
220 } 249 }
221 250
222 bool EmbeddedWorkerDevToolsManager::ServiceWorkerCreated( 251 bool EmbeddedWorkerDevToolsManager::ServiceWorkerCreated(
223 int worker_process_id, 252 int worker_process_id,
224 int worker_route_id, 253 int worker_route_id,
225 const ServiceWorkerIdentifier& service_worker_id) { 254 const ServiceWorkerIdentifier& service_worker_id) {
226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
227 const WorkerId id(worker_process_id, worker_route_id); 256 const WorkerId id(worker_process_id, worker_route_id);
228 WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(service_worker_id); 257 WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(service_worker_id);
229 if (it == workers_.end()) { 258 if (it == workers_.end()) {
230 scoped_ptr<WorkerInfo> info(new WorkerInfo(service_worker_id)); 259 scoped_ptr<WorkerInfo> info(
260 new WorkerInfo(service_worker_id, debug_service_worker_on_start_));
231 workers_.set(id, info.Pass()); 261 workers_.set(id, info.Pass());
232 return false; 262 return debug_service_worker_on_start_;
233 } 263 }
234 MoveToPausedState(id, it); 264 MoveToPausedState(id, it);
235 return true; 265 return true;
236 } 266 }
237 267
238 void EmbeddedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id, 268 void EmbeddedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id,
239 int worker_route_id) { 269 int worker_route_id) {
240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
241 const WorkerId id(worker_process_id, worker_route_id); 271 const WorkerId id(worker_process_id, worker_route_id);
242 WorkerInfoMap::iterator it = workers_.find(id); 272 WorkerInfoMap::iterator it = workers_.find(id);
(...skipping 17 matching lines...) Expand all
260 devtools::Worker::disconnectedFromWorker::kName, NULL) 290 devtools::Worker::disconnectedFromWorker::kName, NULL)
261 ->Serialize(); 291 ->Serialize();
262 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend( 292 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(
263 agent_host, notification); 293 agent_host, notification);
264 agent_host->DetachFromWorker(); 294 agent_host->DetachFromWorker();
265 break; 295 break;
266 } 296 }
267 case WORKER_TERMINATED: 297 case WORKER_TERMINATED:
268 NOTREACHED(); 298 NOTREACHED();
269 break; 299 break;
270 case WORKER_PAUSED: { 300 case WORKER_PAUSED_FOR_REATTACH: {
271 scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(it); 301 scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(it);
272 worker_info->set_state(WORKER_TERMINATED); 302 worker_info->set_state(WORKER_TERMINATED);
273 const WorkerId old_id = worker_info->agent_host()->worker_id(); 303 const WorkerId old_id = worker_info->agent_host()->worker_id();
274 workers_.set(old_id, worker_info.Pass()); 304 workers_.set(old_id, worker_info.Pass());
275 break; 305 break;
276 } 306 }
277 } 307 }
278 } 308 }
279 309
280 void EmbeddedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id, 310 void EmbeddedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id,
281 int worker_route_id) { 311 int worker_route_id) {
282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
283 const WorkerId id(worker_process_id, worker_route_id); 313 const WorkerId id(worker_process_id, worker_route_id);
284 WorkerInfoMap::iterator it = workers_.find(id); 314 WorkerInfoMap::iterator it = workers_.find(id);
285 DCHECK(it != workers_.end()); 315 DCHECK(it != workers_.end());
286 WorkerInfo* info = it->second; 316 WorkerInfo* info = it->second;
287 if (info->state() != WORKER_PAUSED) 317 if (info->state() != WORKER_PAUSED_FOR_REATTACH) {
318 if (!info->debug_on_start())
319 return;
320 RenderProcessHost* rph = RenderProcessHost::FromID(worker_process_id);
321 scoped_refptr<DevToolsAgentHost> agent_host(
322 GetDevToolsAgentHostForWorker(worker_process_id, worker_route_id));
323 DevToolsManagerImpl::GetInstance()->Inspect(rph->GetBrowserContext(),
324 agent_host.get());
288 return; 325 return;
326 }
289 info->agent_host()->ReattachToWorker(id); 327 info->agent_host()->ReattachToWorker(id);
290 info->set_state(WORKER_INSPECTED); 328 info->set_state(WORKER_INSPECTED);
291 } 329 }
292 330
293 void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData( 331 void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData(
294 EmbeddedWorkerDevToolsAgentHost* agent_host) { 332 EmbeddedWorkerDevToolsAgentHost* agent_host) {
295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
296 const WorkerId id(agent_host->worker_id()); 334 const WorkerId id(agent_host->worker_id());
297 scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(id); 335 scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(id);
298 if (worker_info) { 336 if (worker_info) {
299 DCHECK_EQ(WORKER_TERMINATED, worker_info->state()); 337 DCHECK_EQ(WORKER_TERMINATED, worker_info->state());
300 return; 338 return;
301 } 339 }
302 for (WorkerInfoMap::iterator it = workers_.begin(); it != workers_.end(); 340 for (WorkerInfoMap::iterator it = workers_.begin(); it != workers_.end();
303 ++it) { 341 ++it) {
304 if (it->second->agent_host() == agent_host) { 342 if (it->second->agent_host() == agent_host) {
305 DCHECK_EQ(WORKER_PAUSED, it->second->state()); 343 DCHECK_EQ(WORKER_PAUSED_FOR_REATTACH, it->second->state());
306 SendMessageToWorker( 344 SendMessageToWorker(
307 it->first, 345 it->first,
308 new DevToolsAgentMsg_ResumeWorkerContext(it->first.second)); 346 new DevToolsAgentMsg_ResumeWorkerContext(it->first.second));
309 it->second->set_agent_host(NULL); 347 it->second->set_agent_host(NULL);
310 it->second->set_state(WORKER_UNINSPECTED); 348 it->second->set_state(WORKER_UNINSPECTED);
311 return; 349 return;
312 } 350 }
313 } 351 }
314 } 352 }
315 353
(...skipping 17 matching lines...) Expand all
333 break; 371 break;
334 } 372 }
335 return it; 373 return it;
336 } 374 }
337 375
338 void EmbeddedWorkerDevToolsManager::MoveToPausedState( 376 void EmbeddedWorkerDevToolsManager::MoveToPausedState(
339 const WorkerId& id, 377 const WorkerId& id,
340 const WorkerInfoMap::iterator& it) { 378 const WorkerInfoMap::iterator& it) {
341 DCHECK_EQ(WORKER_TERMINATED, it->second->state()); 379 DCHECK_EQ(WORKER_TERMINATED, it->second->state());
342 scoped_ptr<WorkerInfo> info = workers_.take_and_erase(it); 380 scoped_ptr<WorkerInfo> info = workers_.take_and_erase(it);
343 info->set_state(WORKER_PAUSED); 381 info->set_state(WORKER_PAUSED_FOR_REATTACH);
344 workers_.set(id, info.Pass()); 382 workers_.set(id, info.Pass());
345 } 383 }
346 384
347 void EmbeddedWorkerDevToolsManager::ResetForTesting() { 385 void EmbeddedWorkerDevToolsManager::ResetForTesting() {
348 workers_.clear(); 386 workers_.clear();
349 } 387 }
350 388
351 } // namespace content 389 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698