| 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/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/strings/string16.h" | 10 #include "base/strings/string16.h" |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 embedded_worker_->RemoveListener(this); | 186 embedded_worker_->RemoveListener(this); |
| 187 if (context_) | 187 if (context_) |
| 188 context_->RemoveLiveVersion(version_id_); | 188 context_->RemoveLiveVersion(version_id_); |
| 189 // EmbeddedWorker's dtor sends StopWorker if it's still running. | 189 // EmbeddedWorker's dtor sends StopWorker if it's still running. |
| 190 } | 190 } |
| 191 | 191 |
| 192 void ServiceWorkerVersion::SetStatus(Status status) { | 192 void ServiceWorkerVersion::SetStatus(Status status) { |
| 193 if (status_ == status) | 193 if (status_ == status) |
| 194 return; | 194 return; |
| 195 | 195 |
| 196 // Schedule to stop worker after registration successfully completed. | |
| 197 if (status_ == ACTIVATING && status == ACTIVATED && !HasControllee()) | |
| 198 ScheduleStopWorker(); | |
| 199 | |
| 200 status_ = status; | 196 status_ = status; |
| 201 | 197 |
| 202 if (skip_waiting_ && status_ == ACTIVATED) { | 198 if (skip_waiting_ && status_ == ACTIVATED) { |
| 203 for (int request_id : pending_skip_waiting_requests_) | 199 for (int request_id : pending_skip_waiting_requests_) |
| 204 DidSkipWaiting(request_id); | 200 DidSkipWaiting(request_id); |
| 205 pending_skip_waiting_requests_.clear(); | 201 pending_skip_waiting_requests_.clear(); |
| 206 } | 202 } |
| 207 | 203 |
| 208 std::vector<base::Closure> callbacks; | 204 std::vector<base::Closure> callbacks; |
| 209 callbacks.swap(status_change_callbacks_); | 205 callbacks.swap(status_change_callbacks_); |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 } | 588 } |
| 593 | 589 |
| 594 void ServiceWorkerVersion::Doom() { | 590 void ServiceWorkerVersion::Doom() { |
| 595 if (is_doomed_) | 591 if (is_doomed_) |
| 596 return; | 592 return; |
| 597 is_doomed_ = true; | 593 is_doomed_ = true; |
| 598 if (!HasControllee()) | 594 if (!HasControllee()) |
| 599 DoomInternal(); | 595 DoomInternal(); |
| 600 } | 596 } |
| 601 | 597 |
| 598 void ServiceWorkerVersion::SetDevToolsAttached(bool attached) { |
| 599 embedded_worker()->set_devtools_attached(attached); |
| 600 if (!attached && !stop_worker_timer_.IsRunning()) { |
| 601 // If devtools is detached from this version and stop-worker-timer is not |
| 602 // running, try scheduling stop-worker-timer now. |
| 603 ScheduleStopWorker(); |
| 604 } |
| 605 } |
| 606 |
| 602 void ServiceWorkerVersion::OnStarted() { | 607 void ServiceWorkerVersion::OnStarted() { |
| 603 DCHECK_EQ(RUNNING, running_status()); | 608 DCHECK_EQ(RUNNING, running_status()); |
| 604 DCHECK(cache_listener_.get()); | 609 DCHECK(cache_listener_.get()); |
| 605 if (status() == ACTIVATED && !HasControllee()) | 610 ScheduleStopWorker(); |
| 606 ScheduleStopWorker(); | |
| 607 // Fire all start callbacks. | 611 // Fire all start callbacks. |
| 608 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); | 612 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); |
| 609 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStarted(this)); | 613 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStarted(this)); |
| 610 } | 614 } |
| 611 | 615 |
| 612 void ServiceWorkerVersion::OnStopped( | 616 void ServiceWorkerVersion::OnStopped( |
| 613 EmbeddedWorkerInstance::Status old_status) { | 617 EmbeddedWorkerInstance::Status old_status) { |
| 614 DCHECK_EQ(STOPPED, running_status()); | 618 DCHECK_EQ(STOPPED, running_status()); |
| 615 scoped_refptr<ServiceWorkerVersion> protect(this); | 619 scoped_refptr<ServiceWorkerVersion> protect(this); |
| 616 | 620 |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 996 if (pending_skip_waiting_requests_.size() == 1) | 1000 if (pending_skip_waiting_requests_.size() == 1) |
| 997 registration->ActivateWaitingVersionWhenReady(); | 1001 registration->ActivateWaitingVersionWhenReady(); |
| 998 } | 1002 } |
| 999 | 1003 |
| 1000 void ServiceWorkerVersion::DidSkipWaiting(int request_id) { | 1004 void ServiceWorkerVersion::DidSkipWaiting(int request_id) { |
| 1001 if (running_status() == STARTING || running_status() == RUNNING) | 1005 if (running_status() == STARTING || running_status() == RUNNING) |
| 1002 embedded_worker_->SendMessage(ServiceWorkerMsg_DidSkipWaiting(request_id)); | 1006 embedded_worker_->SendMessage(ServiceWorkerMsg_DidSkipWaiting(request_id)); |
| 1003 } | 1007 } |
| 1004 | 1008 |
| 1005 void ServiceWorkerVersion::ScheduleStopWorker() { | 1009 void ServiceWorkerVersion::ScheduleStopWorker() { |
| 1006 if (running_status() != RUNNING) | 1010 // TODO(kinuko): Currently we don't schedule stop-time-worker when the SW has |
| 1011 // controllee, but we should change this default behavior (crbug.com/440259) |
| 1012 if (running_status() != RUNNING || HasControllee()) |
| 1007 return; | 1013 return; |
| 1008 if (stop_worker_timer_.IsRunning()) { | 1014 if (stop_worker_timer_.IsRunning()) { |
| 1009 stop_worker_timer_.Reset(); | 1015 stop_worker_timer_.Reset(); |
| 1010 return; | 1016 return; |
| 1011 } | 1017 } |
| 1012 stop_worker_timer_.Start( | 1018 stop_worker_timer_.Start( |
| 1013 FROM_HERE, base::TimeDelta::FromSeconds(kStopWorkerDelay), | 1019 FROM_HERE, base::TimeDelta::FromSeconds(kStopWorkerDelay), |
| 1014 base::Bind(&ServiceWorkerVersion::StopWorker, | 1020 base::Bind(&ServiceWorkerVersion::StopWorkerIfIdle, |
| 1015 weak_factory_.GetWeakPtr(), | 1021 weak_factory_.GetWeakPtr())); |
| 1016 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback))); | 1022 } |
| 1023 |
| 1024 void ServiceWorkerVersion::StopWorkerIfIdle() { |
| 1025 // Reschedule the stop the worker while there're inflight requests. |
| 1026 // (Note: we'll probably need to revisit this so that we can kill 'bad' SW. |
| 1027 // See https://github.com/slightlyoff/ServiceWorker/issues/527) |
| 1028 if (HasInflightRequests()) { |
| 1029 ScheduleStopWorker(); |
| 1030 return; |
| 1031 } |
| 1032 if (running_status() == STOPPED || !stop_callbacks_.empty()) |
| 1033 return; |
| 1034 embedded_worker_->StopIfIdle(); |
| 1035 } |
| 1036 |
| 1037 bool ServiceWorkerVersion::HasInflightRequests() const { |
| 1038 return |
| 1039 !activate_callbacks_.IsEmpty() || |
| 1040 !install_callbacks_.IsEmpty() || |
| 1041 !fetch_callbacks_.IsEmpty() || |
| 1042 !sync_callbacks_.IsEmpty() || |
| 1043 !notification_click_callbacks_.IsEmpty() || |
| 1044 !push_callbacks_.IsEmpty() || |
| 1045 !geofencing_callbacks_.IsEmpty(); |
| 1017 } | 1046 } |
| 1018 | 1047 |
| 1019 void ServiceWorkerVersion::DoomInternal() { | 1048 void ServiceWorkerVersion::DoomInternal() { |
| 1020 DCHECK(!HasControllee()); | 1049 DCHECK(!HasControllee()); |
| 1021 SetStatus(REDUNDANT); | 1050 SetStatus(REDUNDANT); |
| 1022 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 1051 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
| 1023 if (!context_) | 1052 if (!context_) |
| 1024 return; | 1053 return; |
| 1025 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; | 1054 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; |
| 1026 script_cache_map_.GetResources(&resources); | 1055 script_cache_map_.GetResources(&resources); |
| 1027 context_->storage()->PurgeResources(resources); | 1056 context_->storage()->PurgeResources(resources); |
| 1028 } | 1057 } |
| 1029 | 1058 |
| 1030 } // namespace content | 1059 } // namespace content |
| OLD | NEW |