1// Copyright 2013 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. 4 5#include "content/browser/service_worker/service_worker_dispatcher_host.h" 6 7#include "base/debug/trace_event.h" 8#include "base/logging.h" 9#include "base/strings/utf_string_conversions.h" 10#include "content/browser/message_port_message_filter.h" 11#include "content/browser/message_port_service.h" 12#include "content/browser/service_worker/embedded_worker_registry.h" 13#include "content/browser/service_worker/service_worker_context_core.h" 14#include "content/browser/service_worker/service_worker_context_wrapper.h" 15#include "content/browser/service_worker/service_worker_handle.h" 16#include "content/browser/service_worker/service_worker_registration.h" 17#include "content/browser/service_worker/service_worker_registration_handle.h" 18#include "content/browser/service_worker/service_worker_utils.h" 19#include "content/common/service_worker/embedded_worker_messages.h" 20#include "content/common/service_worker/service_worker_messages.h" 21#include "ipc/ipc_message_macros.h" 22#include "third_party/WebKit/public/platform/WebServiceWorkerError.h" 23#include "url/gurl.h" 24 25using blink::WebServiceWorkerError; 26 27namespace content { 28 29namespace { 30 31const char kShutdownErrorMessage[] = 32 "The Service Worker system has shutdown."; 33 34const uint32 kFilteredMessageClasses[] = { 35 ServiceWorkerMsgStart, 36 EmbeddedWorkerMsgStart, 37}; 38 39// TODO(dominicc): When crbug.com/362214 is fixed, make 40// Can(R|Unr)egisterServiceWorker also check that these are secure 41// origins to defend against compromised renderers. 42bool CanRegisterServiceWorker(const GURL& document_url, 43 const GURL& pattern, 44 const GURL& script_url) { 45 // TODO: Respect Chrome's content settings, if we add a setting for 46 // controlling whether Service Worker is allowed. 47 return document_url.GetOrigin() == pattern.GetOrigin() && 48 document_url.GetOrigin() == script_url.GetOrigin(); 49} 50 51bool CanUnregisterServiceWorker(const GURL& document_url, 52 const GURL& pattern) { 53 // TODO: Respect Chrome's content settings, if we add a setting for 54 // controlling whether Service Worker is allowed. 55 return document_url.GetOrigin() == pattern.GetOrigin(); 56} 57 58bool CanGetRegistration(const GURL& document_url, 59 const GURL& given_document_url) { 60 // TODO: Respect Chrome's content settings, if we add a setting for 61 // controlling whether Service Worker is allowed. 62 return document_url.GetOrigin() == given_document_url.GetOrigin(); 63} 64 65} // namespace 66 67ServiceWorkerDispatcherHost::ServiceWorkerDispatcherHost( 68 int render_process_id, 69 MessagePortMessageFilter* message_port_message_filter) 70 : BrowserMessageFilter(kFilteredMessageClasses, 71 arraysize(kFilteredMessageClasses)), 72 render_process_id_(render_process_id), 73 message_port_message_filter_(message_port_message_filter), 74 channel_ready_(false) { 75} 76 77ServiceWorkerDispatcherHost::~ServiceWorkerDispatcherHost() { 78 if (GetContext()) { 79 GetContext()->RemoveAllProviderHostsForProcess(render_process_id_); 80 GetContext()->embedded_worker_registry()->RemoveChildProcessSender( 81 render_process_id_); 82 } 83} 84 85void ServiceWorkerDispatcherHost::Init( 86 ServiceWorkerContextWrapper* context_wrapper) { 87 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 88 BrowserThread::PostTask( 89 BrowserThread::IO, FROM_HERE, 90 base::Bind(&ServiceWorkerDispatcherHost::Init, 91 this, make_scoped_refptr(context_wrapper))); 92 return; 93 } 94 context_wrapper_ = context_wrapper; 95 GetContext()->embedded_worker_registry()->AddChildProcessSender( 96 render_process_id_, this); 97} 98 99void ServiceWorkerDispatcherHost::OnFilterAdded(IPC::Sender* sender) { 100 TRACE_EVENT0("ServiceWorker", 101 "ServiceWorkerDispatcherHost::OnFilterAdded"); 102 BrowserMessageFilter::OnFilterAdded(sender); 103 channel_ready_ = true; 104 std::vector<IPC::Message*> messages; 105 pending_messages_.release(&messages); 106 for (size_t i = 0; i < messages.size(); ++i) { 107 BrowserMessageFilter::Send(messages[i]); 108 } 109} 110 111void ServiceWorkerDispatcherHost::OnDestruct() const { 112 BrowserThread::DeleteOnIOThread::Destruct(this); 113} 114 115bool ServiceWorkerDispatcherHost::OnMessageReceived( 116 const IPC::Message& message) { 117 bool handled = true; 118 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcherHost, message) 119 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_RegisterServiceWorker, 120 OnRegisterServiceWorker) 121 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_UnregisterServiceWorker, 122 OnUnregisterServiceWorker) 123 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetRegistration, 124 OnGetRegistration) 125 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderCreated, 126 OnProviderCreated) 127 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderDestroyed, 128 OnProviderDestroyed) 129 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetVersionId, 130 OnSetHostedVersionId) 131 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToWorker, 132 OnPostMessageToWorker) 133 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerReadyForInspection, 134 OnWorkerReadyForInspection) 135 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoaded, 136 OnWorkerScriptLoaded) 137 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoadFailed, 138 OnWorkerScriptLoadFailed) 139 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStarted, 140 OnWorkerStarted) 141 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStopped, 142 OnWorkerStopped) 143 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_DidPauseAfterDownload, 144 OnPausedAfterDownload) 145 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportException, 146 OnReportException) 147 IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportConsoleMessage, 148 OnReportConsoleMessage) 149 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount, 150 OnIncrementServiceWorkerRefCount) 151 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount, 152 OnDecrementServiceWorkerRefCount) 153 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementRegistrationRefCount, 154 OnIncrementRegistrationRefCount) 155 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementRegistrationRefCount, 156 OnDecrementRegistrationRefCount) 157 IPC_MESSAGE_UNHANDLED(handled = false) 158 IPC_END_MESSAGE_MAP() 159 160 if (!handled && GetContext()) { 161 handled = 162 GetContext()->embedded_worker_registry()->OnMessageReceived(message); 163 if (!handled) 164 BadMessageReceived(); 165 } 166 167 return handled; 168} 169 170bool ServiceWorkerDispatcherHost::Send(IPC::Message* message) { 171 if (channel_ready_) { 172 BrowserMessageFilter::Send(message); 173 // Don't bother passing through Send()'s result: it's not reliable. 174 return true; 175 } 176 177 pending_messages_.push_back(message); 178 return true; 179} 180 181ServiceWorkerRegistrationHandle* 182ServiceWorkerDispatcherHost::GetOrCreateRegistrationHandle( 183 int provider_id, 184 ServiceWorkerRegistration* registration) { 185 ServiceWorkerRegistrationHandle* handle = 186 FindRegistrationHandle(provider_id, registration->id()); 187 if (handle) { 188 handle->IncrementRefCount(); 189 return handle; 190 } 191 192 scoped_ptr<ServiceWorkerRegistrationHandle> new_handle( 193 new ServiceWorkerRegistrationHandle( 194 GetContext()->AsWeakPtr(), this, provider_id, registration)); 195 handle = new_handle.get(); 196 RegisterServiceWorkerRegistrationHandle(new_handle.Pass()); 197 return handle; 198} 199 200void ServiceWorkerDispatcherHost::RegisterServiceWorkerHandle( 201 scoped_ptr<ServiceWorkerHandle> handle) { 202 int handle_id = handle->handle_id(); 203 handles_.AddWithID(handle.release(), handle_id); 204} 205 206void ServiceWorkerDispatcherHost::RegisterServiceWorkerRegistrationHandle( 207 scoped_ptr<ServiceWorkerRegistrationHandle> handle) { 208 int handle_id = handle->handle_id(); 209 registration_handles_.AddWithID(handle.release(), handle_id); 210} 211 212void ServiceWorkerDispatcherHost::OnRegisterServiceWorker( 213 int thread_id, 214 int request_id, 215 int provider_id, 216 const GURL& pattern, 217 const GURL& script_url) { 218 TRACE_EVENT0("ServiceWorker", 219 "ServiceWorkerDispatcherHost::OnRegisterServiceWorker"); 220 if (!GetContext()) { 221 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError( 222 thread_id, 223 request_id, 224 WebServiceWorkerError::ErrorTypeAbort, 225 base::ASCIIToUTF16(kShutdownErrorMessage))); 226 return; 227 } 228 229 ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost( 230 render_process_id_, provider_id); 231 if (!provider_host) { 232 BadMessageReceived(); 233 return; 234 } 235 if (!provider_host->IsContextAlive()) { 236 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError( 237 thread_id, 238 request_id, 239 WebServiceWorkerError::ErrorTypeAbort, 240 base::ASCIIToUTF16(kShutdownErrorMessage))); 241 return; 242 } 243 244 if (!CanRegisterServiceWorker( 245 provider_host->document_url(), pattern, script_url)) { 246 BadMessageReceived(); 247 return; 248 } 249 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker", 250 "ServiceWorkerDispatcherHost::RegisterServiceWorker", 251 request_id, 252 "Pattern", pattern.spec(), 253 "Script URL", script_url.spec()); 254 GetContext()->RegisterServiceWorker( 255 pattern, 256 script_url, 257 provider_host, 258 base::Bind(&ServiceWorkerDispatcherHost::RegistrationComplete, 259 this, 260 thread_id, 261 provider_id, 262 request_id)); 263} 264 265void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker( 266 int thread_id, 267 int request_id, 268 int provider_id, 269 const GURL& pattern) { 270 TRACE_EVENT0("ServiceWorker", 271 "ServiceWorkerDispatcherHost::OnUnregisterServiceWorker"); 272 if (!GetContext()) { 273 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError( 274 thread_id, 275 request_id, 276 blink::WebServiceWorkerError::ErrorTypeAbort, 277 base::ASCIIToUTF16(kShutdownErrorMessage))); 278 return; 279 } 280 281 ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost( 282 render_process_id_, provider_id); 283 if (!provider_host) { 284 BadMessageReceived(); 285 return; 286 } 287 if (!provider_host->IsContextAlive()) { 288 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError( 289 thread_id, 290 request_id, 291 blink::WebServiceWorkerError::ErrorTypeAbort, 292 base::ASCIIToUTF16(kShutdownErrorMessage))); 293 return; 294 } 295 296 if (!CanUnregisterServiceWorker(provider_host->document_url(), pattern)) { 297 BadMessageReceived(); 298 return; 299 } 300 301 TRACE_EVENT_ASYNC_BEGIN1( 302 "ServiceWorker", 303 "ServiceWorkerDispatcherHost::UnregisterServiceWorker", 304 request_id, 305 "Pattern", pattern.spec()); 306 GetContext()->UnregisterServiceWorker( 307 pattern, 308 base::Bind(&ServiceWorkerDispatcherHost::UnregistrationComplete, 309 this, 310 thread_id, 311 request_id)); 312} 313 314void ServiceWorkerDispatcherHost::OnGetRegistration( 315 int thread_id, 316 int request_id, 317 int provider_id, 318 const GURL& document_url) { 319 TRACE_EVENT0("ServiceWorker", 320 "ServiceWorkerDispatcherHost::OnGetRegistration"); 321 if (!GetContext()) { 322 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError( 323 thread_id, 324 request_id, 325 blink::WebServiceWorkerError::ErrorTypeAbort, 326 base::ASCIIToUTF16(kShutdownErrorMessage))); 327 return; 328 } 329 330 ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost( 331 render_process_id_, provider_id); 332 if (!provider_host) { 333 BadMessageReceived(); 334 return; 335 } 336 if (!provider_host->IsContextAlive()) { 337 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError( 338 thread_id, 339 request_id, 340 blink::WebServiceWorkerError::ErrorTypeAbort, 341 base::ASCIIToUTF16(kShutdownErrorMessage))); 342 return; 343 } 344 345 if (!CanGetRegistration(provider_host->document_url(), document_url)) { 346 BadMessageReceived(); 347 return; 348 } 349 350 DCHECK_CURRENTLY_ON(BrowserThread::IO); 351 if (GetContext()->storage()->IsDisabled()) { 352 SendGetRegistrationError(thread_id, request_id, SERVICE_WORKER_ERROR_ABORT); 353 return; 354 } 355 356 TRACE_EVENT_ASYNC_BEGIN1( 357 "ServiceWorker", 358 "ServiceWorkerDispatcherHost::GetRegistration", 359 request_id, 360 "Document URL", document_url.spec()); 361 362 GetContext()->storage()->FindRegistrationForDocument( 363 document_url, 364 base::Bind(&ServiceWorkerDispatcherHost::GetRegistrationComplete, 365 this, 366 thread_id, 367 provider_id, 368 request_id)); 369} 370 371void ServiceWorkerDispatcherHost::OnPostMessageToWorker( 372 int handle_id, 373 const base::string16& message, 374 const std::vector<int>& sent_message_port_ids) { 375 TRACE_EVENT0("ServiceWorker", 376 "ServiceWorkerDispatcherHost::OnPostMessageToWorker"); 377 if (!GetContext()) 378 return; 379 380 ServiceWorkerHandle* handle = handles_.Lookup(handle_id); 381 if (!handle) { 382 BadMessageReceived(); 383 return; 384 } 385 386 std::vector<int> new_routing_ids; 387 message_port_message_filter_->UpdateMessagePortsWithNewRoutes( 388 sent_message_port_ids, &new_routing_ids); 389 handle->version()->SendMessage( 390 ServiceWorkerMsg_MessageToWorker(message, 391 sent_message_port_ids, 392 new_routing_ids), 393 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); 394} 395 396void ServiceWorkerDispatcherHost::OnProviderCreated(int provider_id) { 397 TRACE_EVENT0("ServiceWorker", 398 "ServiceWorkerDispatcherHost::OnProviderCreated"); 399 if (!GetContext()) 400 return; 401 if (GetContext()->GetProviderHost(render_process_id_, provider_id)) { 402 BadMessageReceived(); 403 return; 404 } 405 scoped_ptr<ServiceWorkerProviderHost> provider_host( 406 new ServiceWorkerProviderHost( 407 render_process_id_, provider_id, GetContext()->AsWeakPtr(), this)); 408 GetContext()->AddProviderHost(provider_host.Pass()); 409} 410 411void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id) { 412 TRACE_EVENT0("ServiceWorker", 413 "ServiceWorkerDispatcherHost::OnProviderDestroyed"); 414 if (!GetContext()) 415 return; 416 if (!GetContext()->GetProviderHost(render_process_id_, provider_id)) { 417 BadMessageReceived(); 418 return; 419 } 420 GetContext()->RemoveProviderHost(render_process_id_, provider_id); 421} 422 423void ServiceWorkerDispatcherHost::OnSetHostedVersionId( 424 int provider_id, int64 version_id) { 425 TRACE_EVENT0("ServiceWorker", 426 "ServiceWorkerDispatcherHost::OnSetHostedVersionId"); 427 if (!GetContext()) 428 return; 429 ServiceWorkerProviderHost* provider_host = 430 GetContext()->GetProviderHost(render_process_id_, provider_id); 431 if (!provider_host) { 432 BadMessageReceived(); 433 return; 434 } 435 if (!provider_host->IsContextAlive()) 436 return; 437 if (!provider_host->SetHostedVersionId(version_id)) 438 BadMessageReceived(); 439} 440 441ServiceWorkerRegistrationHandle* 442ServiceWorkerDispatcherHost::FindRegistrationHandle(int provider_id, 443 int64 registration_id) { 444 for (IDMap<ServiceWorkerRegistrationHandle, IDMapOwnPointer>::iterator 445 iter(®istration_handles_); 446 !iter.IsAtEnd(); 447 iter.Advance()) { 448 ServiceWorkerRegistrationHandle* handle = iter.GetCurrentValue(); 449 DCHECK(handle); 450 if (handle->provider_id() == provider_id && handle->registration() && 451 handle->registration()->id() == registration_id) { 452 return handle; 453 } 454 } 455 return NULL; 456} 457 458void ServiceWorkerDispatcherHost::GetRegistrationObjectInfoAndVersionAttributes( 459 int provider_id, 460 ServiceWorkerRegistration* registration, 461 ServiceWorkerRegistrationObjectInfo* info, 462 ServiceWorkerVersionAttributes* attrs) { 463 ServiceWorkerRegistrationHandle* handle = 464 GetOrCreateRegistrationHandle(provider_id, registration); 465 *info = handle->GetObjectInfo(); 466 467 attrs->installing = handle->CreateServiceWorkerHandleAndPass( 468 registration->installing_version()); 469 attrs->waiting = handle->CreateServiceWorkerHandleAndPass( 470 registration->waiting_version()); 471 attrs->active = handle->CreateServiceWorkerHandleAndPass( 472 registration->active_version()); 473} 474 475void ServiceWorkerDispatcherHost::RegistrationComplete( 476 int thread_id, 477 int provider_id, 478 int request_id, 479 ServiceWorkerStatusCode status, 480 int64 registration_id, 481 int64 version_id) { 482 if (!GetContext()) 483 return; 484 485 if (status != SERVICE_WORKER_OK) { 486 SendRegistrationError(thread_id, request_id, status); 487 return; 488 } 489 490 ServiceWorkerRegistration* registration = 491 GetContext()->GetLiveRegistration(registration_id); 492 DCHECK(registration); 493 494 ServiceWorkerRegistrationObjectInfo info; 495 ServiceWorkerVersionAttributes attrs; 496 GetRegistrationObjectInfoAndVersionAttributes( 497 provider_id, registration, &info, &attrs); 498 499 Send(new ServiceWorkerMsg_ServiceWorkerRegistered( 500 thread_id, request_id, info, attrs)); 501 TRACE_EVENT_ASYNC_END2("ServiceWorker", 502 "ServiceWorkerDispatcherHost::RegisterServiceWorker", 503 request_id, 504 "Registration ID", registration_id, 505 "Version ID", version_id); 506} 507 508void ServiceWorkerDispatcherHost::OnWorkerReadyForInspection( 509 int embedded_worker_id) { 510 TRACE_EVENT0("ServiceWorker", 511 "ServiceWorkerDispatcherHost::OnWorkerReadyForInspection"); 512 if (!GetContext()) 513 return; 514 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry(); 515 if (!registry->CanHandle(embedded_worker_id)) 516 return; 517 registry->OnWorkerReadyForInspection(render_process_id_, embedded_worker_id); 518} 519 520void ServiceWorkerDispatcherHost::OnWorkerScriptLoaded( 521 int embedded_worker_id, 522 int thread_id) { 523 TRACE_EVENT0("ServiceWorker", 524 "ServiceWorkerDispatcherHost::OnWorkerScriptLoaded"); 525 if (!GetContext()) 526 return; 527 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry(); 528 if (!registry->CanHandle(embedded_worker_id)) 529 return; 530 registry->OnWorkerScriptLoaded( 531 render_process_id_, thread_id, embedded_worker_id); 532} 533 534void ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed( 535 int embedded_worker_id) { 536 TRACE_EVENT0("ServiceWorker", 537 "ServiceWorkerDispatcherHost::OnWorkerScriptLoadFailed"); 538 if (!GetContext()) 539 return; 540 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry(); 541 if (!registry->CanHandle(embedded_worker_id)) 542 return; 543 registry->OnWorkerScriptLoadFailed(render_process_id_, embedded_worker_id); 544} 545 546void ServiceWorkerDispatcherHost::OnWorkerStarted(int embedded_worker_id) { 547 TRACE_EVENT0("ServiceWorker", 548 "ServiceWorkerDispatcherHost::OnWorkerStarted"); 549 if (!GetContext()) 550 return; 551 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry(); 552 if (!registry->CanHandle(embedded_worker_id)) 553 return; 554 registry->OnWorkerStarted(render_process_id_, embedded_worker_id); 555} 556 557void ServiceWorkerDispatcherHost::OnWorkerStopped(int embedded_worker_id) { 558 TRACE_EVENT0("ServiceWorker", 559 "ServiceWorkerDispatcherHost::OnWorkerStopped"); 560 if (!GetContext()) 561 return; 562 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry(); 563 if (!registry->CanHandle(embedded_worker_id)) 564 return; 565 registry->OnWorkerStopped(render_process_id_, embedded_worker_id); 566} 567 568void ServiceWorkerDispatcherHost::OnPausedAfterDownload( 569 int embedded_worker_id) { 570 TRACE_EVENT0("ServiceWorker", 571 "ServiceWorkerDispatcherHost::OnPausedAfterDownload"); 572 if (!GetContext()) 573 return; 574 GetContext()->embedded_worker_registry()->OnPausedAfterDownload( 575 render_process_id_, embedded_worker_id); 576} 577 578void ServiceWorkerDispatcherHost::OnReportException( 579 int embedded_worker_id, 580 const base::string16& error_message, 581 int line_number, 582 int column_number, 583 const GURL& source_url) { 584 TRACE_EVENT0("ServiceWorker", 585 "ServiceWorkerDispatcherHost::OnReportException"); 586 if (!GetContext()) 587 return; 588 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry(); 589 if (!registry->CanHandle(embedded_worker_id)) 590 return; 591 registry->OnReportException(embedded_worker_id, 592 error_message, 593 line_number, 594 column_number, 595 source_url); 596} 597 598void ServiceWorkerDispatcherHost::OnReportConsoleMessage( 599 int embedded_worker_id, 600 const EmbeddedWorkerHostMsg_ReportConsoleMessage_Params& params) { 601 TRACE_EVENT0("ServiceWorker", 602 "ServiceWorkerDispatcherHost::OnReportConsoleMessage"); 603 if (!GetContext()) 604 return; 605 EmbeddedWorkerRegistry* registry = GetContext()->embedded_worker_registry(); 606 if (!registry->CanHandle(embedded_worker_id)) 607 return; 608 registry->OnReportConsoleMessage(embedded_worker_id, 609 params.source_identifier, 610 params.message_level, 611 params.message, 612 params.line_number, 613 params.source_url); 614} 615 616void ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount( 617 int handle_id) { 618 TRACE_EVENT0("ServiceWorker", 619 "ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount"); 620 ServiceWorkerHandle* handle = handles_.Lookup(handle_id); 621 if (!handle) { 622 BadMessageReceived(); 623 return; 624 } 625 handle->IncrementRefCount(); 626} 627 628void ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount( 629 int handle_id) { 630 TRACE_EVENT0("ServiceWorker", 631 "ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount"); 632 ServiceWorkerHandle* handle = handles_.Lookup(handle_id); 633 if (!handle) { 634 BadMessageReceived(); 635 return; 636 } 637 handle->DecrementRefCount(); 638 if (handle->HasNoRefCount()) 639 handles_.Remove(handle_id); 640} 641 642void ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount( 643 int registration_handle_id) { 644 TRACE_EVENT0("ServiceWorker", 645 "ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount"); 646 ServiceWorkerRegistrationHandle* handle = 647 registration_handles_.Lookup(registration_handle_id); 648 if (!handle) { 649 BadMessageReceived(); 650 return; 651 } 652 handle->IncrementRefCount(); 653} 654 655void ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount( 656 int registration_handle_id) { 657 TRACE_EVENT0("ServiceWorker", 658 "ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount"); 659 ServiceWorkerRegistrationHandle* handle = 660 registration_handles_.Lookup(registration_handle_id); 661 if (!handle) { 662 BadMessageReceived(); 663 return; 664 } 665 handle->DecrementRefCount(); 666 if (handle->HasNoRefCount()) 667 registration_handles_.Remove(registration_handle_id); 668} 669 670void ServiceWorkerDispatcherHost::UnregistrationComplete( 671 int thread_id, 672 int request_id, 673 ServiceWorkerStatusCode status) { 674 if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) { 675 SendUnregistrationError(thread_id, request_id, status); 676 return; 677 } 678 const bool is_success = (status == SERVICE_WORKER_OK); 679 Send(new ServiceWorkerMsg_ServiceWorkerUnregistered(thread_id, 680 request_id, 681 is_success)); 682 TRACE_EVENT_ASYNC_END1( 683 "ServiceWorker", 684 "ServiceWorkerDispatcherHost::UnregisterServiceWorker", 685 request_id, 686 "Status", status); 687} 688 689void ServiceWorkerDispatcherHost::GetRegistrationComplete( 690 int thread_id, 691 int provider_id, 692 int request_id, 693 ServiceWorkerStatusCode status, 694 const scoped_refptr<ServiceWorkerRegistration>& registration) { 695 TRACE_EVENT_ASYNC_END1("ServiceWorker", 696 "ServiceWorkerDispatcherHost::GetRegistration", 697 request_id, 698 "Registration ID", 699 registration.get() ? registration->id() 700 : kInvalidServiceWorkerRegistrationId); 701 if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) { 702 SendGetRegistrationError(thread_id, request_id, status); 703 return; 704 } 705 706 ServiceWorkerRegistrationObjectInfo info; 707 ServiceWorkerVersionAttributes attrs; 708 if (status == SERVICE_WORKER_OK) { 709 DCHECK(registration.get()); 710 if (!registration->is_uninstalling()) { 711 GetRegistrationObjectInfoAndVersionAttributes( 712 provider_id, registration.get(), &info, &attrs); 713 } 714 } 715 716 Send(new ServiceWorkerMsg_DidGetRegistration( 717 thread_id, request_id, info, attrs)); 718} 719 720void ServiceWorkerDispatcherHost::SendRegistrationError( 721 int thread_id, 722 int request_id, 723 ServiceWorkerStatusCode status) { 724 base::string16 error_message; 725 blink::WebServiceWorkerError::ErrorType error_type; 726 GetServiceWorkerRegistrationStatusResponse( 727 status, &error_type, &error_message); 728 Send(new ServiceWorkerMsg_ServiceWorkerRegistrationError( 729 thread_id, request_id, error_type, error_message)); 730} 731 732void ServiceWorkerDispatcherHost::SendUnregistrationError( 733 int thread_id, 734 int request_id, 735 ServiceWorkerStatusCode status) { 736 base::string16 error_message; 737 blink::WebServiceWorkerError::ErrorType error_type; 738 GetServiceWorkerRegistrationStatusResponse( 739 status, &error_type, &error_message); 740 Send(new ServiceWorkerMsg_ServiceWorkerUnregistrationError( 741 thread_id, request_id, error_type, error_message)); 742} 743 744void ServiceWorkerDispatcherHost::SendGetRegistrationError( 745 int thread_id, 746 int request_id, 747 ServiceWorkerStatusCode status) { 748 base::string16 error_message; 749 blink::WebServiceWorkerError::ErrorType error_type; 750 GetServiceWorkerRegistrationStatusResponse( 751 status, &error_type, &error_message); 752 Send(new ServiceWorkerMsg_ServiceWorkerGetRegistrationError( 753 thread_id, request_id, error_type, error_message)); 754} 755 756ServiceWorkerContextCore* ServiceWorkerDispatcherHost::GetContext() { 757 return context_wrapper_->context(); 758} 759 760} // namespace content 761