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.
5 #include "content/browser/service_worker/service_worker_version.h"
7 #include "base/command_line.h"
8 #include "base/stl_util.h"
9 #include "base/strings/string16.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_instance.h"
13 #include "content/browser/service_worker/embedded_worker_registry.h"
14 #include "content/browser/service_worker/service_worker_context_core.h"
15 #include "content/browser/service_worker/service_worker_registration.h"
16 #include "content/browser/service_worker/service_worker_utils.h"
17 #include "content/common/service_worker/service_worker_messages.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/common/content_switches.h"
23 typedef ServiceWorkerVersion::StatusCallback StatusCallback
;
24 typedef ServiceWorkerVersion::MessageCallback MessageCallback
;
28 // Default delay for scheduled stop.
29 // (Note that if all references to the version is dropped the worker
30 // is also stopped without delay)
31 const int64 kStopWorkerDelay
= 30; // 30 secs.
33 // Default delay for scheduled update.
34 const int kUpdateDelaySeconds
= 1;
36 void RunSoon(const base::Closure
& callback
) {
37 if (!callback
.is_null())
38 base::MessageLoop::current()->PostTask(FROM_HERE
, callback
);
41 template <typename CallbackArray
, typename Arg
>
42 void RunCallbacks(ServiceWorkerVersion
* version
,
43 CallbackArray
* callbacks_ptr
,
45 CallbackArray callbacks
;
46 callbacks
.swap(*callbacks_ptr
);
47 scoped_refptr
<ServiceWorkerVersion
> protect(version
);
48 for (typename
CallbackArray::const_iterator i
= callbacks
.begin();
49 i
!= callbacks
.end(); ++i
)
53 template <typename IDMAP
, typename Method
, typename Params
>
54 void RunIDMapCallbacks(IDMAP
* callbacks
, Method method
, const Params
& params
) {
55 typename
IDMAP::iterator
iter(callbacks
);
56 while (!iter
.IsAtEnd()) {
57 DispatchToMethod(iter
.GetCurrentValue(), method
, params
);
63 // A callback adapter to start a |task| after StartWorker.
64 void RunTaskAfterStartWorker(
65 base::WeakPtr
<ServiceWorkerVersion
> version
,
66 const StatusCallback
& error_callback
,
67 const base::Closure
& task
,
68 ServiceWorkerStatusCode status
) {
69 if (status
!= SERVICE_WORKER_OK
) {
70 if (!error_callback
.is_null())
71 error_callback
.Run(status
);
74 if (version
->running_status() != ServiceWorkerVersion::RUNNING
) {
75 // We've tried to start the worker (and it has succeeded), but
76 // it looks it's not running yet.
77 NOTREACHED() << "The worker's not running after successful StartWorker";
78 if (!error_callback
.is_null())
79 error_callback
.Run(SERVICE_WORKER_ERROR_START_WORKER_FAILED
);
85 void RunErrorFetchCallback(const ServiceWorkerVersion::FetchCallback
& callback
,
86 ServiceWorkerStatusCode status
) {
88 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK
,
89 ServiceWorkerResponse());
92 void RunErrorMessageCallback(
93 const std::vector
<int>& sent_message_port_ids
,
94 const ServiceWorkerVersion::StatusCallback
& callback
,
95 ServiceWorkerStatusCode status
) {
96 // Transfering the message ports failed, so destroy the ports.
97 for (int message_port_id
: sent_message_port_ids
) {
98 MessagePortService::GetInstance()->ClosePort(message_port_id
);
100 callback
.Run(status
);
105 ServiceWorkerVersion::ServiceWorkerVersion(
106 ServiceWorkerRegistration
* registration
,
107 const GURL
& script_url
,
109 base::WeakPtr
<ServiceWorkerContextCore
> context
)
110 : version_id_(version_id
),
111 registration_id_(kInvalidServiceWorkerVersionId
),
112 script_url_(script_url
),
115 script_cache_map_(this, context
),
117 weak_factory_(this) {
119 DCHECK(registration
);
121 registration_id_
= registration
->id();
122 scope_
= registration
->pattern();
124 context_
->AddLiveVersion(this);
125 embedded_worker_
= context_
->embedded_worker_registry()->CreateWorker();
126 embedded_worker_
->AddListener(this);
129 ServiceWorkerVersion::~ServiceWorkerVersion() {
130 embedded_worker_
->RemoveListener(this);
132 context_
->RemoveLiveVersion(version_id_
);
133 // EmbeddedWorker's dtor sends StopWorker if it's still running.
136 void ServiceWorkerVersion::SetStatus(Status status
) {
137 if (status_
== status
)
140 // Schedule to stop worker after registration successfully completed.
141 if (status_
== ACTIVATING
&& status
== ACTIVATED
&& !HasControllee())
142 ScheduleStopWorker();
146 std::vector
<base::Closure
> callbacks
;
147 callbacks
.swap(status_change_callbacks_
);
148 for (std::vector
<base::Closure
>::const_iterator i
= callbacks
.begin();
149 i
!= callbacks
.end(); ++i
) {
153 FOR_EACH_OBSERVER(Listener
, listeners_
, OnVersionStateChanged(this));
156 void ServiceWorkerVersion::RegisterStatusChangeCallback(
157 const base::Closure
& callback
) {
158 status_change_callbacks_
.push_back(callback
);
161 ServiceWorkerVersionInfo
ServiceWorkerVersion::GetInfo() {
162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
163 return ServiceWorkerVersionInfo(
168 embedded_worker()->process_id(),
169 embedded_worker()->thread_id(),
170 embedded_worker()->worker_devtools_agent_route_id());
173 void ServiceWorkerVersion::StartWorker(const StatusCallback
& callback
) {
174 StartWorker(false, callback
);
177 void ServiceWorkerVersion::StartWorker(
178 bool pause_after_download
,
179 const StatusCallback
& callback
) {
180 switch (running_status()) {
182 RunSoon(base::Bind(callback
, SERVICE_WORKER_OK
));
185 RunSoon(base::Bind(callback
, SERVICE_WORKER_ERROR_START_WORKER_FAILED
));
189 start_callbacks_
.push_back(callback
);
190 if (running_status() == STOPPED
) {
191 DCHECK(!cache_listener_
.get());
192 cache_listener_
.reset(new ServiceWorkerCacheListener(this, context_
));
193 embedded_worker_
->Start(
197 pause_after_download
,
198 base::Bind(&ServiceWorkerVersion::OnStartMessageSent
,
199 weak_factory_
.GetWeakPtr()));
205 void ServiceWorkerVersion::StopWorker(const StatusCallback
& callback
) {
206 if (running_status() == STOPPED
) {
207 RunSoon(base::Bind(callback
, SERVICE_WORKER_OK
));
210 if (stop_callbacks_
.empty()) {
211 ServiceWorkerStatusCode status
= embedded_worker_
->Stop();
212 if (status
!= SERVICE_WORKER_OK
) {
213 RunSoon(base::Bind(callback
, status
));
217 stop_callbacks_
.push_back(callback
);
220 void ServiceWorkerVersion::ScheduleUpdate() {
221 if (update_timer_
.IsRunning()) {
222 update_timer_
.Reset();
226 FROM_HERE
, base::TimeDelta::FromSeconds(kUpdateDelaySeconds
),
227 base::Bind(&ServiceWorkerVersion::StartUpdate
,
228 weak_factory_
.GetWeakPtr()));
231 void ServiceWorkerVersion::DeferScheduledUpdate() {
232 if (update_timer_
.IsRunning())
233 update_timer_
.Reset();
236 void ServiceWorkerVersion::StartUpdate() {
237 update_timer_
.Stop();
240 ServiceWorkerRegistration
* registration
=
241 context_
->GetLiveRegistration(registration_id_
);
242 if (!registration
|| !registration
->GetNewestVersion())
244 context_
->UpdateServiceWorker(registration
);
247 void ServiceWorkerVersion::SendMessage(
248 const IPC::Message
& message
, const StatusCallback
& callback
) {
249 if (running_status() != RUNNING
) {
250 // Schedule calling this method after starting the worker.
251 StartWorker(base::Bind(&RunTaskAfterStartWorker
,
252 weak_factory_
.GetWeakPtr(), callback
,
253 base::Bind(&self::SendMessage
,
254 weak_factory_
.GetWeakPtr(),
255 message
, callback
)));
259 ServiceWorkerStatusCode status
= embedded_worker_
->SendMessage(message
);
260 RunSoon(base::Bind(callback
, status
));
263 void ServiceWorkerVersion::DispatchMessageEvent(
264 const base::string16
& message
,
265 const std::vector
<int>& sent_message_port_ids
,
266 const StatusCallback
& callback
) {
267 for (int message_port_id
: sent_message_port_ids
) {
268 MessagePortService::GetInstance()->HoldMessages(message_port_id
);
271 DispatchMessageEventInternal(message
, sent_message_port_ids
, callback
);
274 void ServiceWorkerVersion::DispatchMessageEventInternal(
275 const base::string16
& message
,
276 const std::vector
<int>& sent_message_port_ids
,
277 const StatusCallback
& callback
) {
278 if (running_status() != RUNNING
) {
279 // Schedule calling this method after starting the worker.
280 StartWorker(base::Bind(
281 &RunTaskAfterStartWorker
, weak_factory_
.GetWeakPtr(),
282 base::Bind(&RunErrorMessageCallback
, sent_message_port_ids
, callback
),
283 base::Bind(&self::DispatchMessageEventInternal
,
284 weak_factory_
.GetWeakPtr(), message
, sent_message_port_ids
,
289 MessagePortMessageFilter
* filter
=
290 embedded_worker_
->message_port_message_filter();
291 std::vector
<int> new_routing_ids
;
292 filter
->UpdateMessagePortsWithNewRoutes(sent_message_port_ids
,
294 ServiceWorkerStatusCode status
=
295 embedded_worker_
->SendMessage(ServiceWorkerMsg_MessageToWorker(
296 message
, sent_message_port_ids
, new_routing_ids
));
297 RunSoon(base::Bind(callback
, status
));
300 void ServiceWorkerVersion::DispatchInstallEvent(
301 int active_version_id
,
302 const StatusCallback
& callback
) {
303 DCHECK_EQ(INSTALLING
, status()) << status();
305 if (running_status() != RUNNING
) {
306 // Schedule calling this method after starting the worker.
308 base::Bind(&RunTaskAfterStartWorker
,
309 weak_factory_
.GetWeakPtr(),
311 base::Bind(&self::DispatchInstallEventAfterStartWorker
,
312 weak_factory_
.GetWeakPtr(),
316 DispatchInstallEventAfterStartWorker(active_version_id
, callback
);
320 void ServiceWorkerVersion::DispatchActivateEvent(
321 const StatusCallback
& callback
) {
322 DCHECK_EQ(ACTIVATING
, status()) << status();
324 if (running_status() != RUNNING
) {
325 // Schedule calling this method after starting the worker.
327 base::Bind(&RunTaskAfterStartWorker
,
328 weak_factory_
.GetWeakPtr(),
330 base::Bind(&self::DispatchActivateEventAfterStartWorker
,
331 weak_factory_
.GetWeakPtr(),
334 DispatchActivateEventAfterStartWorker(callback
);
338 void ServiceWorkerVersion::DispatchFetchEvent(
339 const ServiceWorkerFetchRequest
& request
,
340 const base::Closure
& prepare_callback
,
341 const FetchCallback
& fetch_callback
) {
342 DCHECK_EQ(ACTIVATED
, status()) << status();
344 if (running_status() != RUNNING
) {
345 // Schedule calling this method after starting the worker.
346 StartWorker(base::Bind(&RunTaskAfterStartWorker
,
347 weak_factory_
.GetWeakPtr(),
348 base::Bind(&RunErrorFetchCallback
, fetch_callback
),
349 base::Bind(&self::DispatchFetchEvent
,
350 weak_factory_
.GetWeakPtr(),
357 prepare_callback
.Run();
359 int request_id
= fetch_callbacks_
.Add(new FetchCallback(fetch_callback
));
360 ServiceWorkerStatusCode status
= embedded_worker_
->SendMessage(
361 ServiceWorkerMsg_FetchEvent(request_id
, request
));
362 if (status
!= SERVICE_WORKER_OK
) {
363 fetch_callbacks_
.Remove(request_id
);
364 RunSoon(base::Bind(&RunErrorFetchCallback
,
366 SERVICE_WORKER_ERROR_FAILED
));
370 void ServiceWorkerVersion::DispatchSyncEvent(const StatusCallback
& callback
) {
371 DCHECK_EQ(ACTIVATED
, status()) << status();
373 if (!CommandLine::ForCurrentProcess()->HasSwitch(
374 switches::kEnableServiceWorkerSync
)) {
375 callback
.Run(SERVICE_WORKER_ERROR_ABORT
);
379 if (running_status() != RUNNING
) {
380 // Schedule calling this method after starting the worker.
381 StartWorker(base::Bind(&RunTaskAfterStartWorker
,
382 weak_factory_
.GetWeakPtr(), callback
,
383 base::Bind(&self::DispatchSyncEvent
,
384 weak_factory_
.GetWeakPtr(),
389 int request_id
= sync_callbacks_
.Add(new StatusCallback(callback
));
390 ServiceWorkerStatusCode status
= embedded_worker_
->SendMessage(
391 ServiceWorkerMsg_SyncEvent(request_id
));
392 if (status
!= SERVICE_WORKER_OK
) {
393 sync_callbacks_
.Remove(request_id
);
394 RunSoon(base::Bind(callback
, status
));
398 void ServiceWorkerVersion::DispatchPushEvent(const StatusCallback
& callback
,
399 const std::string
& data
) {
400 DCHECK_EQ(ACTIVATED
, status()) << status();
402 if (!CommandLine::ForCurrentProcess()->HasSwitch(
403 switches::kEnableExperimentalWebPlatformFeatures
)) {
404 callback
.Run(SERVICE_WORKER_ERROR_ABORT
);
408 if (running_status() != RUNNING
) {
409 // Schedule calling this method after starting the worker.
410 StartWorker(base::Bind(&RunTaskAfterStartWorker
,
411 weak_factory_
.GetWeakPtr(), callback
,
412 base::Bind(&self::DispatchPushEvent
,
413 weak_factory_
.GetWeakPtr(),
418 int request_id
= push_callbacks_
.Add(new StatusCallback(callback
));
419 ServiceWorkerStatusCode status
= embedded_worker_
->SendMessage(
420 ServiceWorkerMsg_PushEvent(request_id
, data
));
421 if (status
!= SERVICE_WORKER_OK
) {
422 push_callbacks_
.Remove(request_id
);
423 RunSoon(base::Bind(callback
, status
));
427 void ServiceWorkerVersion::DispatchGeofencingEvent(
428 const StatusCallback
& callback
,
429 blink::WebGeofencingEventType event_type
,
430 const std::string
& region_id
,
431 const blink::WebCircularGeofencingRegion
& region
) {
432 DCHECK_EQ(ACTIVATED
, status()) << status();
434 if (!CommandLine::ForCurrentProcess()->HasSwitch(
435 switches::kEnableExperimentalWebPlatformFeatures
)) {
436 callback
.Run(SERVICE_WORKER_ERROR_ABORT
);
440 if (running_status() != RUNNING
) {
441 // Schedule calling this method after starting the worker.
442 StartWorker(base::Bind(&RunTaskAfterStartWorker
,
443 weak_factory_
.GetWeakPtr(),
445 base::Bind(&self::DispatchGeofencingEvent
,
446 weak_factory_
.GetWeakPtr(),
454 int request_id
= geofencing_callbacks_
.Add(new StatusCallback(callback
));
455 ServiceWorkerStatusCode status
=
456 embedded_worker_
->SendMessage(ServiceWorkerMsg_GeofencingEvent(
457 request_id
, event_type
, region_id
, region
));
458 if (status
!= SERVICE_WORKER_OK
) {
459 geofencing_callbacks_
.Remove(request_id
);
460 RunSoon(base::Bind(callback
, status
));
464 void ServiceWorkerVersion::AddControllee(
465 ServiceWorkerProviderHost
* provider_host
) {
466 DCHECK(!ContainsKey(controllee_map_
, provider_host
));
467 int controllee_id
= controllee_by_id_
.Add(provider_host
);
468 controllee_map_
[provider_host
] = controllee_id
;
469 if (stop_worker_timer_
.IsRunning())
470 stop_worker_timer_
.Stop();
473 void ServiceWorkerVersion::RemoveControllee(
474 ServiceWorkerProviderHost
* provider_host
) {
475 ControlleeMap::iterator found
= controllee_map_
.find(provider_host
);
476 DCHECK(found
!= controllee_map_
.end());
477 controllee_by_id_
.Remove(found
->second
);
478 controllee_map_
.erase(found
);
481 FOR_EACH_OBSERVER(Listener
, listeners_
, OnNoControllees(this));
486 ScheduleStopWorker();
489 void ServiceWorkerVersion::AddListener(Listener
* listener
) {
490 listeners_
.AddObserver(listener
);
493 void ServiceWorkerVersion::RemoveListener(Listener
* listener
) {
494 listeners_
.RemoveObserver(listener
);
497 void ServiceWorkerVersion::Doom() {
501 if (!HasControllee())
505 void ServiceWorkerVersion::OnStarted() {
506 DCHECK_EQ(RUNNING
, running_status());
507 DCHECK(cache_listener_
.get());
508 if (status() == ACTIVATED
&& !HasControllee())
509 ScheduleStopWorker();
510 // Fire all start callbacks.
511 RunCallbacks(this, &start_callbacks_
, SERVICE_WORKER_OK
);
512 FOR_EACH_OBSERVER(Listener
, listeners_
, OnWorkerStarted(this));
515 void ServiceWorkerVersion::OnStopped() {
516 DCHECK_EQ(STOPPED
, running_status());
517 scoped_refptr
<ServiceWorkerVersion
> protect(this);
519 // Fire all stop callbacks.
520 RunCallbacks(this, &stop_callbacks_
, SERVICE_WORKER_OK
);
522 // Let all start callbacks fail.
524 this, &start_callbacks_
, SERVICE_WORKER_ERROR_START_WORKER_FAILED
);
526 // Let all message callbacks fail (this will also fire and clear all
527 // callbacks for events).
528 // TODO(kinuko): Consider if we want to add queue+resend mechanism here.
529 RunIDMapCallbacks(&activate_callbacks_
,
530 &StatusCallback::Run
,
531 MakeTuple(SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED
));
532 RunIDMapCallbacks(&install_callbacks_
,
533 &StatusCallback::Run
,
534 MakeTuple(SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED
));
535 RunIDMapCallbacks(&fetch_callbacks_
,
537 MakeTuple(SERVICE_WORKER_ERROR_FAILED
,
538 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK
,
539 ServiceWorkerResponse()));
540 RunIDMapCallbacks(&sync_callbacks_
,
541 &StatusCallback::Run
,
542 MakeTuple(SERVICE_WORKER_ERROR_FAILED
));
543 RunIDMapCallbacks(&push_callbacks_
,
544 &StatusCallback::Run
,
545 MakeTuple(SERVICE_WORKER_ERROR_FAILED
));
546 RunIDMapCallbacks(&geofencing_callbacks_
,
547 &StatusCallback::Run
,
548 MakeTuple(SERVICE_WORKER_ERROR_FAILED
));
550 FOR_EACH_OBSERVER(Listener
, listeners_
, OnWorkerStopped(this));
552 // There should be no more communication from/to a stopped worker. Deleting
553 // the listener prevents any pending completion callbacks from causing
554 // messages to be sent to the stopped worker.
555 cache_listener_
.reset();
558 void ServiceWorkerVersion::OnReportException(
559 const base::string16
& error_message
,
562 const GURL
& source_url
) {
567 this, error_message
, line_number
, column_number
, source_url
));
570 void ServiceWorkerVersion::OnReportConsoleMessage(int source_identifier
,
572 const base::string16
& message
,
574 const GURL
& source_url
) {
575 FOR_EACH_OBSERVER(Listener
,
577 OnReportConsoleMessage(this,
585 bool ServiceWorkerVersion::OnMessageReceived(const IPC::Message
& message
) {
587 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerVersion
, message
)
588 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientDocuments
,
589 OnGetClientDocuments
)
590 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ActivateEventFinished
,
591 OnActivateEventFinished
)
592 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_InstallEventFinished
,
593 OnInstallEventFinished
)
594 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FetchEventFinished
,
595 OnFetchEventFinished
)
596 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SyncEventFinished
,
598 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PushEventFinished
,
600 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GeofencingEventFinished
,
601 OnGeofencingEventFinished
)
602 IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument
,
603 OnPostMessageToDocument
)
604 IPC_MESSAGE_UNHANDLED(handled
= false)
605 IPC_END_MESSAGE_MAP()
609 void ServiceWorkerVersion::OnStartMessageSent(
610 ServiceWorkerStatusCode status
) {
611 if (status
!= SERVICE_WORKER_OK
)
612 RunCallbacks(this, &start_callbacks_
, status
);
615 void ServiceWorkerVersion::DispatchInstallEventAfterStartWorker(
616 int active_version_id
,
617 const StatusCallback
& callback
) {
618 DCHECK_EQ(RUNNING
, running_status())
619 << "Worker stopped too soon after it was started.";
621 int request_id
= install_callbacks_
.Add(new StatusCallback(callback
));
622 ServiceWorkerStatusCode status
= embedded_worker_
->SendMessage(
623 ServiceWorkerMsg_InstallEvent(request_id
, active_version_id
));
624 if (status
!= SERVICE_WORKER_OK
) {
625 install_callbacks_
.Remove(request_id
);
626 RunSoon(base::Bind(callback
, status
));
630 void ServiceWorkerVersion::DispatchActivateEventAfterStartWorker(
631 const StatusCallback
& callback
) {
632 DCHECK_EQ(RUNNING
, running_status())
633 << "Worker stopped too soon after it was started.";
635 int request_id
= activate_callbacks_
.Add(new StatusCallback(callback
));
636 ServiceWorkerStatusCode status
=
637 embedded_worker_
->SendMessage(ServiceWorkerMsg_ActivateEvent(request_id
));
638 if (status
!= SERVICE_WORKER_OK
) {
639 activate_callbacks_
.Remove(request_id
);
640 RunSoon(base::Bind(callback
, status
));
644 void ServiceWorkerVersion::OnGetClientDocuments(int request_id
) {
645 std::vector
<int> client_ids
;
646 ControlleeByIDMap::iterator
it(&controllee_by_id_
);
647 TRACE_EVENT0("ServiceWorker",
648 "ServiceWorkerVersion::OnGetClientDocuments");
649 while (!it
.IsAtEnd()) {
650 client_ids
.push_back(it
.GetCurrentKey());
653 // Don't bother if it's no longer running.
654 if (running_status() == RUNNING
) {
655 embedded_worker_
->SendMessage(
656 ServiceWorkerMsg_DidGetClientDocuments(request_id
, client_ids
));
660 void ServiceWorkerVersion::OnActivateEventFinished(
662 blink::WebServiceWorkerEventResult result
) {
663 DCHECK(ACTIVATING
== status() ||
664 REDUNDANT
== status()) << status();
665 TRACE_EVENT0("ServiceWorker",
666 "ServiceWorkerVersion::OnActivateEventFinished");
668 StatusCallback
* callback
= activate_callbacks_
.Lookup(request_id
);
670 NOTREACHED() << "Got unexpected message: " << request_id
;
673 ServiceWorkerStatusCode rv
= SERVICE_WORKER_OK
;
674 if (result
== blink::WebServiceWorkerEventResultRejected
||
675 status() != ACTIVATING
) {
676 rv
= SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED
;
679 scoped_refptr
<ServiceWorkerVersion
> protect(this);
681 activate_callbacks_
.Remove(request_id
);
684 void ServiceWorkerVersion::OnInstallEventFinished(
686 blink::WebServiceWorkerEventResult result
) {
687 DCHECK_EQ(INSTALLING
, status()) << status();
688 TRACE_EVENT0("ServiceWorker",
689 "ServiceWorkerVersion::OnInstallEventFinished");
691 StatusCallback
* callback
= install_callbacks_
.Lookup(request_id
);
693 NOTREACHED() << "Got unexpected message: " << request_id
;
696 ServiceWorkerStatusCode status
= SERVICE_WORKER_OK
;
697 if (result
== blink::WebServiceWorkerEventResultRejected
)
698 status
= SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED
;
700 scoped_refptr
<ServiceWorkerVersion
> protect(this);
701 callback
->Run(status
);
702 install_callbacks_
.Remove(request_id
);
705 void ServiceWorkerVersion::OnFetchEventFinished(
707 ServiceWorkerFetchEventResult result
,
708 const ServiceWorkerResponse
& response
) {
709 TRACE_EVENT1("ServiceWorker",
710 "ServiceWorkerVersion::OnFetchEventFinished",
711 "Request id", request_id
);
712 FetchCallback
* callback
= fetch_callbacks_
.Lookup(request_id
);
714 NOTREACHED() << "Got unexpected message: " << request_id
;
718 scoped_refptr
<ServiceWorkerVersion
> protect(this);
719 callback
->Run(SERVICE_WORKER_OK
, result
, response
);
720 fetch_callbacks_
.Remove(request_id
);
723 void ServiceWorkerVersion::OnSyncEventFinished(
725 TRACE_EVENT1("ServiceWorker",
726 "ServiceWorkerVersion::OnSyncEventFinished",
727 "Request id", request_id
);
728 StatusCallback
* callback
= sync_callbacks_
.Lookup(request_id
);
730 NOTREACHED() << "Got unexpected message: " << request_id
;
734 scoped_refptr
<ServiceWorkerVersion
> protect(this);
735 callback
->Run(SERVICE_WORKER_OK
);
736 sync_callbacks_
.Remove(request_id
);
739 void ServiceWorkerVersion::OnPushEventFinished(
741 TRACE_EVENT1("ServiceWorker",
742 "ServiceWorkerVersion::OnPushEventFinished",
743 "Request id", request_id
);
744 StatusCallback
* callback
= push_callbacks_
.Lookup(request_id
);
746 NOTREACHED() << "Got unexpected message: " << request_id
;
750 scoped_refptr
<ServiceWorkerVersion
> protect(this);
751 callback
->Run(SERVICE_WORKER_OK
);
752 push_callbacks_
.Remove(request_id
);
755 void ServiceWorkerVersion::OnGeofencingEventFinished(int request_id
) {
756 TRACE_EVENT1("ServiceWorker",
757 "ServiceWorkerVersion::OnGeofencingEventFinished",
760 StatusCallback
* callback
= geofencing_callbacks_
.Lookup(request_id
);
762 NOTREACHED() << "Got unexpected message: " << request_id
;
766 scoped_refptr
<ServiceWorkerVersion
> protect(this);
767 callback
->Run(SERVICE_WORKER_OK
);
768 geofencing_callbacks_
.Remove(request_id
);
771 void ServiceWorkerVersion::OnPostMessageToDocument(
773 const base::string16
& message
,
774 const std::vector
<int>& sent_message_port_ids
) {
775 TRACE_EVENT1("ServiceWorker",
776 "ServiceWorkerVersion::OnPostMessageToDocument",
777 "Client id", client_id
);
778 ServiceWorkerProviderHost
* provider_host
=
779 controllee_by_id_
.Lookup(client_id
);
780 if (!provider_host
) {
781 // The client may already have been closed, just ignore.
784 provider_host
->PostMessage(message
, sent_message_port_ids
);
787 void ServiceWorkerVersion::ScheduleStopWorker() {
788 if (running_status() != RUNNING
)
790 if (stop_worker_timer_
.IsRunning()) {
791 stop_worker_timer_
.Reset();
794 stop_worker_timer_
.Start(
795 FROM_HERE
, base::TimeDelta::FromSeconds(kStopWorkerDelay
),
796 base::Bind(&ServiceWorkerVersion::StopWorker
,
797 weak_factory_
.GetWeakPtr(),
798 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
)));
801 void ServiceWorkerVersion::DoomInternal() {
802 DCHECK(!HasControllee());
803 SetStatus(REDUNDANT
);
804 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
807 std::vector
<ServiceWorkerDatabase::ResourceRecord
> resources
;
808 script_cache_map_
.GetResources(&resources
);
809 context_
->storage()->PurgeResources(resources
);
812 } // namespace content