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

Side by Side Diff: content/browser/devtools/protocol/service_worker_handler.cc

Issue 2354973003: [DevTools] Move subtargets functionality from ServiceWorker to Target domain. (Closed)
Patch Set: review comments Created 4 years, 2 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/protocol/service_worker_handler.h" 5 #include "content/browser/devtools/protocol/service_worker_handler.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/containers/scoped_ptr_hash_map.h" 8 #include "base/containers/scoped_ptr_hash_map.h"
9 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 14 matching lines...) Expand all
25 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/devtools_agent_host.h" 26 #include "content/public/browser/devtools_agent_host.h"
27 #include "content/public/browser/render_frame_host.h" 27 #include "content/public/browser/render_frame_host.h"
28 #include "content/public/browser/render_process_host.h" 28 #include "content/public/browser/render_process_host.h"
29 #include "content/public/browser/storage_partition.h" 29 #include "content/public/browser/storage_partition.h"
30 #include "content/public/browser/web_contents.h" 30 #include "content/public/browser/web_contents.h"
31 #include "content/public/common/push_event_payload.h" 31 #include "content/public/common/push_event_payload.h"
32 #include "content/public/common/push_messaging_status.h" 32 #include "content/public/common/push_messaging_status.h"
33 #include "url/gurl.h" 33 #include "url/gurl.h"
34 34
35 // Windows headers will redefine SendMessage.
36 #ifdef SendMessage
37 #undef SendMessage
38 #endif
39
40 namespace content { 35 namespace content {
41 namespace devtools { 36 namespace devtools {
42 namespace service_worker { 37 namespace service_worker {
43 38
44 using Response = DevToolsProtocolClient::Response; 39 using Response = DevToolsProtocolClient::Response;
45 40
46 namespace { 41 namespace {
47 42
48 using ScopeAgentsMap =
49 std::map<GURL, std::unique_ptr<ServiceWorkerDevToolsAgentHost::List>>;
50
51 void ResultNoOp(bool success) { 43 void ResultNoOp(bool success) {
52 } 44 }
53 45
54 void StatusNoOp(ServiceWorkerStatusCode status) { 46 void StatusNoOp(ServiceWorkerStatusCode status) {
55 } 47 }
56 48
57 void StatusNoOpKeepingRegistration( 49 void StatusNoOpKeepingRegistration(
58 scoped_refptr<content::ServiceWorkerRegistration> protect, 50 scoped_refptr<content::ServiceWorkerRegistration> protect,
59 ServiceWorkerStatusCode status) { 51 ServiceWorkerStatusCode status) {
60 } 52 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 base::Int64ToString(version_info.registration_id)) 121 base::Int64ToString(version_info.registration_id))
130 ->set_script_url(version_info.script_url.spec()) 122 ->set_script_url(version_info.script_url.spec())
131 ->set_running_status( 123 ->set_running_status(
132 GetVersionRunningStatusString(version_info.running_status)) 124 GetVersionRunningStatusString(version_info.running_status))
133 ->set_status(GetVersionStatusString(version_info.status)) 125 ->set_status(GetVersionStatusString(version_info.status))
134 ->set_script_last_modified( 126 ->set_script_last_modified(
135 version_info.script_last_modified.ToDoubleT()) 127 version_info.script_last_modified.ToDoubleT())
136 ->set_script_response_time( 128 ->set_script_response_time(
137 version_info.script_response_time.ToDoubleT()) 129 version_info.script_response_time.ToDoubleT())
138 ->set_controlled_clients(clients)); 130 ->set_controlled_clients(clients));
131 scoped_refptr<DevToolsAgentHostImpl> host(
132 ServiceWorkerDevToolsManager::GetInstance()
133 ->GetDevToolsAgentHostForWorker(
134 version_info.process_id,
135 version_info.devtools_agent_route_id));
136 if (host)
137 version->set_target_id(host->GetId());
139 return version; 138 return version;
140 } 139 }
141 140
142 scoped_refptr<ServiceWorkerRegistration> CreateRegistrationDictionaryValue( 141 scoped_refptr<ServiceWorkerRegistration> CreateRegistrationDictionaryValue(
143 const ServiceWorkerRegistrationInfo& registration_info) { 142 const ServiceWorkerRegistrationInfo& registration_info) {
144 scoped_refptr<ServiceWorkerRegistration> registration( 143 scoped_refptr<ServiceWorkerRegistration> registration(
145 ServiceWorkerRegistration::Create() 144 ServiceWorkerRegistration::Create()
146 ->set_registration_id( 145 ->set_registration_id(
147 base::Int64ToString(registration_info.registration_id)) 146 base::Int64ToString(registration_info.registration_id))
148 ->set_scope_url(registration_info.pattern.spec()) 147 ->set_scope_url(registration_info.pattern.spec())
149 ->set_is_deleted(registration_info.delete_flag == 148 ->set_is_deleted(registration_info.delete_flag ==
150 ServiceWorkerRegistrationInfo::IS_DELETED)); 149 ServiceWorkerRegistrationInfo::IS_DELETED));
151 return registration; 150 return registration;
152 } 151 }
153 152
154 void GetMatchingHostsByScopeMap(
155 const ServiceWorkerDevToolsAgentHost::List& agent_hosts,
156 const std::set<GURL>& urls,
157 ScopeAgentsMap* scope_agents_map) {
158 std::set<base::StringPiece> host_name_set;
159 for (const GURL& url : urls)
160 host_name_set.insert(url.host_piece());
161 for (const auto& host : agent_hosts) {
162 if (host_name_set.find(host->scope().host_piece()) == host_name_set.end())
163 continue;
164 const auto& it = scope_agents_map->find(host->scope());
165 if (it == scope_agents_map->end()) {
166 std::unique_ptr<ServiceWorkerDevToolsAgentHost::List> new_list(
167 new ServiceWorkerDevToolsAgentHost::List());
168 new_list->push_back(host);
169 (*scope_agents_map)[host->scope()] = std::move(new_list);
170 } else {
171 it->second->push_back(host);
172 }
173 }
174 }
175
176 void AddEligibleHosts(const ServiceWorkerDevToolsAgentHost::List& list,
177 ServiceWorkerDevToolsAgentHost::Map* result) {
178 base::Time last_installed_time;
179 base::Time last_doomed_time;
180 for (const auto& host : list) {
181 if (host->version_installed_time() > last_installed_time)
182 last_installed_time = host->version_installed_time();
183 if (host->version_doomed_time() > last_doomed_time)
184 last_doomed_time = host->version_doomed_time();
185 }
186 for (const auto& host : list) {
187 // We don't attech old redundant Service Workers when there is newer
188 // installed Service Worker.
189 if (host->version_doomed_time().is_null() ||
190 (last_installed_time < last_doomed_time &&
191 last_doomed_time == host->version_doomed_time())) {
192 (*result)[host->GetId()] = host;
193 }
194 }
195 }
196
197 ServiceWorkerDevToolsAgentHost::Map GetMatchingServiceWorkers(
198 BrowserContext* browser_context,
199 const std::set<GURL>& urls) {
200 ServiceWorkerDevToolsAgentHost::Map result;
201 if (!browser_context)
202 return result;
203
204 ServiceWorkerDevToolsAgentHost::List agent_hosts;
205 ServiceWorkerDevToolsManager::GetInstance()
206 ->AddAllAgentHostsForBrowserContext(browser_context, &agent_hosts);
207
208 ScopeAgentsMap scope_agents_map;
209 GetMatchingHostsByScopeMap(agent_hosts, urls, &scope_agents_map);
210
211 for (const auto& it : scope_agents_map)
212 AddEligibleHosts(*it.second.get(), &result);
213
214 return result;
215 }
216
217 void StopServiceWorkerOnIO(scoped_refptr<ServiceWorkerContextWrapper> context, 153 void StopServiceWorkerOnIO(scoped_refptr<ServiceWorkerContextWrapper> context,
218 int64_t version_id) { 154 int64_t version_id) {
219 if (content::ServiceWorkerVersion* version = 155 if (content::ServiceWorkerVersion* version =
220 context->GetLiveVersion(version_id)) { 156 context->GetLiveVersion(version_id)) {
221 version->StopWorker(base::Bind(&StatusNoOp)); 157 version->StopWorker(base::Bind(&StatusNoOp));
222 } 158 }
223 } 159 }
224 160
225 void GetDevToolsRouteInfoOnIO( 161 void GetDevToolsRouteInfoOnIO(
226 scoped_refptr<ServiceWorkerContextWrapper> context, 162 scoped_refptr<ServiceWorkerContextWrapper> context,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 render_frame_host->GetSiteInstance()); 234 render_frame_host->GetSiteInstance());
299 DCHECK(partition); 235 DCHECK(partition);
300 context_ = static_cast<ServiceWorkerContextWrapper*>( 236 context_ = static_cast<ServiceWorkerContextWrapper*>(
301 partition->GetServiceWorkerContext()); 237 partition->GetServiceWorkerContext());
302 } 238 }
303 239
304 void ServiceWorkerHandler::SetClient(std::unique_ptr<Client> client) { 240 void ServiceWorkerHandler::SetClient(std::unique_ptr<Client> client) {
305 client_.swap(client); 241 client_.swap(client);
306 } 242 }
307 243
308 void ServiceWorkerHandler::UpdateHosts() {
309 if (!enabled_)
310 return;
311
312 urls_.clear();
313 BrowserContext* browser_context = nullptr;
314 if (render_frame_host_) {
315 for (FrameTreeNode* node :
316 render_frame_host_->frame_tree_node()->frame_tree()->Nodes())
317 urls_.insert(node->current_url());
318
319 browser_context = render_frame_host_->GetProcess()->GetBrowserContext();
320 }
321
322 ServiceWorkerDevToolsAgentHost::Map old_hosts = attached_hosts_;
323 ServiceWorkerDevToolsAgentHost::Map new_hosts =
324 GetMatchingServiceWorkers(browser_context, urls_);
325
326 for (const auto& pair : old_hosts) {
327 if (new_hosts.find(pair.first) == new_hosts.end())
328 ReportWorkerTerminated(pair.second.get());
329 }
330
331 for (const auto& pair : new_hosts) {
332 if (old_hosts.find(pair.first) == old_hosts.end())
333 ReportWorkerCreated(pair.second.get());
334 }
335 }
336
337 void ServiceWorkerHandler::Detached() { 244 void ServiceWorkerHandler::Detached() {
338 Disable(); 245 Disable();
339 } 246 }
340 247
341 Response ServiceWorkerHandler::Enable() { 248 Response ServiceWorkerHandler::Enable() {
342 if (enabled_) 249 if (enabled_)
343 return Response::OK(); 250 return Response::OK();
344 if (!context_) 251 if (!context_)
345 return Response::InternalError("Could not connect to the context"); 252 return Response::InternalError("Could not connect to the context");
346 enabled_ = true; 253 enabled_ = true;
347 254
348 ServiceWorkerDevToolsManager::GetInstance()->AddObserver(this);
349
350 context_watcher_ = new ServiceWorkerContextWatcher( 255 context_watcher_ = new ServiceWorkerContextWatcher(
351 context_, base::Bind(&ServiceWorkerHandler::OnWorkerRegistrationUpdated, 256 context_, base::Bind(&ServiceWorkerHandler::OnWorkerRegistrationUpdated,
352 weak_factory_.GetWeakPtr()), 257 weak_factory_.GetWeakPtr()),
353 base::Bind(&ServiceWorkerHandler::OnWorkerVersionUpdated, 258 base::Bind(&ServiceWorkerHandler::OnWorkerVersionUpdated,
354 weak_factory_.GetWeakPtr()), 259 weak_factory_.GetWeakPtr()),
355 base::Bind(&ServiceWorkerHandler::OnErrorReported, 260 base::Bind(&ServiceWorkerHandler::OnErrorReported,
356 weak_factory_.GetWeakPtr())); 261 weak_factory_.GetWeakPtr()));
357 context_watcher_->Start(); 262 context_watcher_->Start();
358 263
359 UpdateHosts();
360 return Response::OK(); 264 return Response::OK();
361 } 265 }
362 266
363 Response ServiceWorkerHandler::Disable() { 267 Response ServiceWorkerHandler::Disable() {
364 if (!enabled_) 268 if (!enabled_)
365 return Response::OK(); 269 return Response::OK();
366 enabled_ = false; 270 enabled_ = false;
367 271
368 ServiceWorkerDevToolsManager::GetInstance()->RemoveObserver(this);
369 ClearForceUpdate(); 272 ClearForceUpdate();
370 for (const auto& pair : attached_hosts_)
371 pair.second->DetachClient(this);
372 attached_hosts_.clear();
373 DCHECK(context_watcher_); 273 DCHECK(context_watcher_);
374 context_watcher_->Stop(); 274 context_watcher_->Stop();
375 context_watcher_ = nullptr; 275 context_watcher_ = nullptr;
376 return Response::OK(); 276 return Response::OK();
377 } 277 }
378 278
379 Response ServiceWorkerHandler::SendMessage(
380 const std::string& worker_id,
381 const std::string& message) {
382 auto it = attached_hosts_.find(worker_id);
383 if (it == attached_hosts_.end())
384 return Response::InternalError("Not connected to the worker");
385 it->second->DispatchProtocolMessage(message);
386 return Response::OK();
387 }
388
389 Response ServiceWorkerHandler::Stop(
390 const std::string& worker_id) {
391 auto it = attached_hosts_.find(worker_id);
392 if (it == attached_hosts_.end())
393 return Response::InternalError("Not connected to the worker");
394 it->second->UnregisterWorker();
395 return Response::OK();
396 }
397
398 Response ServiceWorkerHandler::Unregister(const std::string& scope_url) { 279 Response ServiceWorkerHandler::Unregister(const std::string& scope_url) {
399 if (!enabled_) 280 if (!enabled_)
400 return Response::OK(); 281 return Response::OK();
401 if (!context_) 282 if (!context_)
402 return CreateContextErrorResponse(); 283 return CreateContextErrorResponse();
403 context_->UnregisterServiceWorker(GURL(scope_url), base::Bind(&ResultNoOp)); 284 context_->UnregisterServiceWorker(GURL(scope_url), base::Bind(&ResultNoOp));
404 return Response::OK(); 285 return Response::OK();
405 } 286 }
406 287
407 Response ServiceWorkerHandler::StartWorker(const std::string& scope_url) { 288 Response ServiceWorkerHandler::StartWorker(const std::string& scope_url) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 render_frame_host_->GetSiteInstance())); 390 render_frame_host_->GetSiteInstance()));
510 BackgroundSyncContext* sync_context = partition->GetBackgroundSyncContext(); 391 BackgroundSyncContext* sync_context = partition->GetBackgroundSyncContext();
511 392
512 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 393 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
513 base::Bind(&DispatchSyncEventOnIO, context_, 394 base::Bind(&DispatchSyncEventOnIO, context_,
514 make_scoped_refptr(sync_context), 395 make_scoped_refptr(sync_context),
515 GURL(origin), id, tag, last_chance)); 396 GURL(origin), id, tag, last_chance));
516 return Response::OK(); 397 return Response::OK();
517 } 398 }
518 399
519 Response ServiceWorkerHandler::GetTargetInfo(
520 const std::string& target_id,
521 scoped_refptr<TargetInfo>* target_info) {
522 scoped_refptr<DevToolsAgentHost> agent_host(
523 DevToolsAgentHost::GetForId(target_id));
524 if (!agent_host)
525 return Response::InvalidParams("targetId");
526 *target_info =
527 TargetInfo::Create()
528 ->set_id(agent_host->GetId())
529 ->set_type(agent_host->GetType())
530 ->set_title(agent_host->GetTitle())
531 ->set_url(agent_host->GetURL().spec());
532 return Response::OK();
533 }
534
535 Response ServiceWorkerHandler::ActivateTarget(const std::string& target_id) {
536 scoped_refptr<DevToolsAgentHost> agent_host(
537 DevToolsAgentHost::GetForId(target_id));
538 if (!agent_host)
539 return Response::InvalidParams("targetId");
540 agent_host->Activate();
541 return Response::OK();
542 }
543
544 void ServiceWorkerHandler::OpenNewDevToolsWindow(int process_id, 400 void ServiceWorkerHandler::OpenNewDevToolsWindow(int process_id,
545 int devtools_agent_route_id) { 401 int devtools_agent_route_id) {
546 scoped_refptr<DevToolsAgentHostImpl> agent_host( 402 scoped_refptr<DevToolsAgentHostImpl> agent_host(
547 ServiceWorkerDevToolsManager::GetInstance() 403 ServiceWorkerDevToolsManager::GetInstance()
548 ->GetDevToolsAgentHostForWorker(process_id, devtools_agent_route_id)); 404 ->GetDevToolsAgentHostForWorker(process_id, devtools_agent_route_id));
549 if (!agent_host.get()) 405 if (!agent_host.get())
550 return; 406 return;
551 agent_host->Inspect(); 407 agent_host->Inspect();
552 } 408 }
553 409
(...skipping 27 matching lines...) Expand all
581 WorkerErrorReportedParams::Create()->set_error_message( 437 WorkerErrorReportedParams::Create()->set_error_message(
582 ServiceWorkerErrorMessage::Create() 438 ServiceWorkerErrorMessage::Create()
583 ->set_error_message(base::UTF16ToUTF8(info.error_message)) 439 ->set_error_message(base::UTF16ToUTF8(info.error_message))
584 ->set_registration_id(base::Int64ToString(registration_id)) 440 ->set_registration_id(base::Int64ToString(registration_id))
585 ->set_version_id(base::Int64ToString(version_id)) 441 ->set_version_id(base::Int64ToString(version_id))
586 ->set_source_url(info.source_url.spec()) 442 ->set_source_url(info.source_url.spec())
587 ->set_line_number(info.line_number) 443 ->set_line_number(info.line_number)
588 ->set_column_number(info.column_number))); 444 ->set_column_number(info.column_number)));
589 } 445 }
590 446
591 void ServiceWorkerHandler::DispatchProtocolMessage(
592 DevToolsAgentHost* host,
593 const std::string& message) {
594
595 auto it = attached_hosts_.find(host->GetId());
596 if (it == attached_hosts_.end())
597 return; // Already disconnected.
598
599 client_->DispatchMessage(
600 DispatchMessageParams::Create()->
601 set_worker_id(host->GetId())->
602 set_message(message));
603 }
604
605 void ServiceWorkerHandler::AgentHostClosed(
606 DevToolsAgentHost* host,
607 bool replaced_with_another_client) {
608 client_->WorkerTerminated(WorkerTerminatedParams::Create()->
609 set_worker_id(host->GetId()));
610 attached_hosts_.erase(host->GetId());
611 }
612
613 void ServiceWorkerHandler::WorkerCreated(
614 ServiceWorkerDevToolsAgentHost* host) {
615 BrowserContext* browser_context = nullptr;
616 if (render_frame_host_)
617 browser_context = render_frame_host_->GetProcess()->GetBrowserContext();
618
619 auto hosts = GetMatchingServiceWorkers(browser_context, urls_);
620 if (hosts.find(host->GetId()) != hosts.end() && !host->IsAttached() &&
621 !host->IsPausedForDebugOnStart())
622 host->PauseForDebugOnStart();
623 }
624
625 void ServiceWorkerHandler::WorkerReadyForInspection(
626 ServiceWorkerDevToolsAgentHost* host) {
627 if (ServiceWorkerDevToolsManager::GetInstance()
628 ->debug_service_worker_on_start()) {
629 // When debug_service_worker_on_start is true, a new DevTools window will
630 // be opend in ServiceWorkerDevToolsManager::WorkerReadyForInspection.
631 return;
632 }
633 UpdateHosts();
634 }
635
636 void ServiceWorkerHandler::WorkerVersionInstalled(
637 ServiceWorkerDevToolsAgentHost* host) {
638 UpdateHosts();
639 }
640 void ServiceWorkerHandler::WorkerVersionDoomed(
641 ServiceWorkerDevToolsAgentHost* host) {
642 UpdateHosts();
643 }
644
645 void ServiceWorkerHandler::WorkerDestroyed(
646 ServiceWorkerDevToolsAgentHost* host) {
647 UpdateHosts();
648 }
649
650 void ServiceWorkerHandler::ReportWorkerCreated(
651 ServiceWorkerDevToolsAgentHost* host) {
652 if (host->IsAttached())
653 return;
654 attached_hosts_[host->GetId()] = host;
655 host->AttachClient(this);
656 client_->WorkerCreated(WorkerCreatedParams::Create()
657 ->set_worker_id(host->GetId())
658 ->set_url(host->GetURL().spec())
659 ->set_version_id(base::Int64ToString(
660 host->service_worker_version_id())));
661 }
662
663 void ServiceWorkerHandler::ReportWorkerTerminated(
664 ServiceWorkerDevToolsAgentHost* host) {
665 auto it = attached_hosts_.find(host->GetId());
666 if (it == attached_hosts_.end())
667 return;
668 host->DetachClient(this);
669 client_->WorkerTerminated(WorkerTerminatedParams::Create()->
670 set_worker_id(host->GetId()));
671 attached_hosts_.erase(it);
672 }
673
674 void ServiceWorkerHandler::ClearForceUpdate() { 447 void ServiceWorkerHandler::ClearForceUpdate() {
675 if (context_) 448 if (context_)
676 context_->SetForceUpdateOnPageLoad(false); 449 context_->SetForceUpdateOnPageLoad(false);
677 } 450 }
678 451
679 } // namespace service_worker 452 } // namespace service_worker
680 } // namespace devtools 453 } // namespace devtools
681 } // namespace content 454 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/devtools/protocol/service_worker_handler.h ('k') | content/browser/devtools/protocol/target_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698