OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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/service_worker/service_worker_version.h" | 5 #include "content/browser/service_worker/service_worker_version.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "base/strings/string16.h" | 9 #include "base/strings/string16.h" |
10 #include "content/browser/message_port_message_filter.h" | 10 #include "content/browser/message_port_message_filter.h" |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
129 embedded_worker_->RemoveListener(this); | 129 embedded_worker_->RemoveListener(this); |
130 if (context_) | 130 if (context_) |
131 context_->RemoveLiveVersion(version_id_); | 131 context_->RemoveLiveVersion(version_id_); |
132 // EmbeddedWorker's dtor sends StopWorker if it's still running. | 132 // EmbeddedWorker's dtor sends StopWorker if it's still running. |
133 } | 133 } |
134 | 134 |
135 void ServiceWorkerVersion::SetStatus(Status status) { | 135 void ServiceWorkerVersion::SetStatus(Status status) { |
136 if (status_ == status) | 136 if (status_ == status) |
137 return; | 137 return; |
138 | 138 |
139 // Schedule to stop worker after registration successfully completed. | |
140 if (status_ == ACTIVATING && status == ACTIVATED && !HasControllee()) | |
141 ScheduleStopWorker(); | |
142 | |
143 status_ = status; | 139 status_ = status; |
144 | 140 |
145 std::vector<base::Closure> callbacks; | 141 std::vector<base::Closure> callbacks; |
146 callbacks.swap(status_change_callbacks_); | 142 callbacks.swap(status_change_callbacks_); |
147 for (const auto& callback : callbacks) | 143 for (const auto& callback : callbacks) |
148 callback.Run(); | 144 callback.Run(); |
149 | 145 |
150 FOR_EACH_OBSERVER(Listener, listeners_, OnVersionStateChanged(this)); | 146 FOR_EACH_OBSERVER(Listener, listeners_, OnVersionStateChanged(this)); |
151 } | 147 } |
152 | 148 |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
525 } | 521 } |
526 | 522 |
527 void ServiceWorkerVersion::Doom() { | 523 void ServiceWorkerVersion::Doom() { |
528 if (is_doomed_) | 524 if (is_doomed_) |
529 return; | 525 return; |
530 is_doomed_ = true; | 526 is_doomed_ = true; |
531 if (!HasControllee()) | 527 if (!HasControllee()) |
532 DoomInternal(); | 528 DoomInternal(); |
533 } | 529 } |
534 | 530 |
531 void ServiceWorkerVersion::SetDevToolsAttached(bool attached) { | |
532 if (!attached && !stop_worker_timer_.IsRunning()) { | |
533 // If devtools is detached from this version and stop-worker-timer is not | |
534 // running, try scheduling stop-worker-timer now. | |
535 ScheduleStopWorker(); | |
536 } | |
537 embedded_worker()->set_devtools_attached(attached); | |
pfeldman
2014/12/15 05:57:04
Do this first for clarity.
kinuko
2014/12/15 06:39:14
Done.
| |
538 } | |
539 | |
535 void ServiceWorkerVersion::OnStarted() { | 540 void ServiceWorkerVersion::OnStarted() { |
536 DCHECK_EQ(RUNNING, running_status()); | 541 DCHECK_EQ(RUNNING, running_status()); |
537 DCHECK(cache_listener_.get()); | 542 DCHECK(cache_listener_.get()); |
538 if (status() == ACTIVATED && !HasControllee()) | 543 ScheduleStopWorker(); |
539 ScheduleStopWorker(); | |
540 // Fire all start callbacks. | 544 // Fire all start callbacks. |
541 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); | 545 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); |
542 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStarted(this)); | 546 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStarted(this)); |
543 } | 547 } |
544 | 548 |
545 void ServiceWorkerVersion::OnStopped( | 549 void ServiceWorkerVersion::OnStopped( |
546 EmbeddedWorkerInstance::Status old_status) { | 550 EmbeddedWorkerInstance::Status old_status) { |
547 DCHECK_EQ(STOPPED, running_status()); | 551 DCHECK_EQ(STOPPED, running_status()); |
548 scoped_refptr<ServiceWorkerVersion> protect(this); | 552 scoped_refptr<ServiceWorkerVersion> protect(this); |
549 | 553 |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
869 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 873 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
870 | 874 |
871 if (running_status() != RUNNING) | 875 if (running_status() != RUNNING) |
872 return; | 876 return; |
873 | 877 |
874 embedded_worker_->SendMessage(ServiceWorkerMsg_FocusClientResponse( | 878 embedded_worker_->SendMessage(ServiceWorkerMsg_FocusClientResponse( |
875 request_id, result)); | 879 request_id, result)); |
876 } | 880 } |
877 | 881 |
878 void ServiceWorkerVersion::ScheduleStopWorker() { | 882 void ServiceWorkerVersion::ScheduleStopWorker() { |
879 if (running_status() != RUNNING) | 883 // TODO(kinuko): Currently we don't schedule stop-time-worker when the SW has |
884 // controllee, but we should change this default behavior (crbug.com/440259) | |
885 if (running_status() != RUNNING || HasControllee()) | |
880 return; | 886 return; |
881 if (stop_worker_timer_.IsRunning()) { | 887 if (stop_worker_timer_.IsRunning()) { |
882 stop_worker_timer_.Reset(); | 888 stop_worker_timer_.Reset(); |
883 return; | 889 return; |
884 } | 890 } |
885 stop_worker_timer_.Start( | 891 stop_worker_timer_.Start( |
886 FROM_HERE, base::TimeDelta::FromSeconds(kStopWorkerDelay), | 892 FROM_HERE, base::TimeDelta::FromSeconds(kStopWorkerDelay), |
887 base::Bind(&ServiceWorkerVersion::StopWorker, | 893 base::Bind(&ServiceWorkerVersion::StopWorkerIfIdle, |
888 weak_factory_.GetWeakPtr(), | 894 weak_factory_.GetWeakPtr())); |
889 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback))); | 895 } |
896 | |
897 void ServiceWorkerVersion::StopWorkerIfIdle() { | |
898 // Reschedule the stop the worker while there're inflight requests. | |
899 // (Note: we'll probably need to revisit this so that we can kill 'bad' SW. | |
900 // See https://github.com/slightlyoff/ServiceWorker/issues/527) | |
901 if (HasInflightRequests()) { | |
902 ScheduleStopWorker(); | |
903 return; | |
904 } | |
905 if (running_status() == STOPPED || !stop_callbacks_.empty()) | |
906 return; | |
907 embedded_worker_->StopIfIdle(); | |
908 } | |
909 | |
910 bool ServiceWorkerVersion::HasInflightRequests() const { | |
911 return | |
912 !activate_callbacks_.IsEmpty() || | |
913 !install_callbacks_.IsEmpty() || | |
914 !fetch_callbacks_.IsEmpty() || | |
915 !sync_callbacks_.IsEmpty() || | |
916 !notification_click_callbacks_.IsEmpty() || | |
917 !push_callbacks_.IsEmpty() || | |
918 !geofencing_callbacks_.IsEmpty(); | |
890 } | 919 } |
891 | 920 |
892 void ServiceWorkerVersion::DoomInternal() { | 921 void ServiceWorkerVersion::DoomInternal() { |
893 DCHECK(!HasControllee()); | 922 DCHECK(!HasControllee()); |
894 SetStatus(REDUNDANT); | 923 SetStatus(REDUNDANT); |
895 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 924 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
896 if (!context_) | 925 if (!context_) |
897 return; | 926 return; |
898 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; | 927 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; |
899 script_cache_map_.GetResources(&resources); | 928 script_cache_map_.GetResources(&resources); |
900 context_->storage()->PurgeResources(resources); | 929 context_->storage()->PurgeResources(resources); |
901 } | 930 } |
902 | 931 |
903 } // namespace content | 932 } // namespace content |
OLD | NEW |