Chromium Code Reviews| 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 |