summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormichaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-23 23:53:37 +0000
committermichaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-23 23:53:37 +0000
commitb37ea77f80650f9bf88aeedfb0650463e0df6253 (patch)
treea051b435104ee3ceab6bd02c573f203d433499d0
parent5cfbddc9cc972f5133f26664dbf5810bb569cd04 (diff)
downloadchromium_src-b37ea77f80650f9bf88aeedfb0650463e0df6253.zip
chromium_src-b37ea77f80650f9bf88aeedfb0650463e0df6253.tar.gz
chromium_src-b37ea77f80650f9bf88aeedfb0650463e0df6253.tar.bz2
Chromium: Adds a mechanism to pause the serviceworker startup sequence after downloading the main script and then to resume. This is to give the browser process a chance to compare the old and new script during a softupdate.
BUG=371671 Review URL: https://codereview.chromium.org/345463002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@279233 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/service_worker/embedded_worker_instance.cc31
-rw-r--r--content/browser/service_worker/embedded_worker_instance.h12
-rw-r--r--content/browser/service_worker/embedded_worker_instance_unittest.cc2
-rw-r--r--content/browser/service_worker/embedded_worker_registry.cc14
-rw-r--r--content/browser/service_worker/embedded_worker_registry.h1
-rw-r--r--content/browser/service_worker/service_worker_browsertest.cc40
-rw-r--r--content/browser/service_worker/service_worker_dispatcher_host.cc10
-rw-r--r--content/browser/service_worker/service_worker_dispatcher_host.h1
-rw-r--r--content/browser/service_worker/service_worker_register_job.cc29
-rw-r--r--content/browser/service_worker/service_worker_register_job.h9
-rw-r--r--content/browser/service_worker/service_worker_version.cc4
-rw-r--r--content/browser/service_worker/service_worker_version.h1
-rw-r--r--content/common/service_worker/embedded_worker_messages.h13
-rw-r--r--content/renderer/service_worker/embedded_worker_context_client.cc4
-rw-r--r--content/renderer/service_worker/embedded_worker_context_client.h1
-rw-r--r--content/renderer/service_worker/embedded_worker_dispatcher.cc27
-rw-r--r--content/renderer/service_worker/embedded_worker_dispatcher.h1
17 files changed, 176 insertions, 24 deletions
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc
index fd2d201..e66f2d1 100644
--- a/content/browser/service_worker/embedded_worker_instance.cc
+++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -56,7 +56,7 @@ void RegisterToWorkerDevToolsManager(
const ServiceWorkerContextCore* const service_worker_context,
int64 service_worker_version_id,
const base::Callback<void(int worker_devtools_agent_route_id,
- bool pause_on_start)>& callback) {
+ bool wait_for_debugger)>& callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(BrowserThread::UI,
FROM_HERE,
@@ -68,11 +68,11 @@ void RegisterToWorkerDevToolsManager(
return;
}
int worker_devtools_agent_route_id = MSG_ROUTING_NONE;
- bool pause_on_start = false;
+ bool wait_for_debugger = false;
if (RenderProcessHost* rph = RenderProcessHost::FromID(process_id)) {
// |rph| may be NULL in unit tests.
worker_devtools_agent_route_id = rph->GetNextRoutingID();
- pause_on_start =
+ wait_for_debugger =
EmbeddedWorkerDevToolsManager::GetInstance()->ServiceWorkerCreated(
process_id,
worker_devtools_agent_route_id,
@@ -82,7 +82,7 @@ void RegisterToWorkerDevToolsManager(
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
- base::Bind(callback, worker_devtools_agent_route_id, pause_on_start));
+ base::Bind(callback, worker_devtools_agent_route_id, wait_for_debugger));
}
} // namespace
@@ -100,6 +100,7 @@ EmbeddedWorkerInstance::~EmbeddedWorkerInstance() {
void EmbeddedWorkerInstance::Start(int64 service_worker_version_id,
const GURL& scope,
const GURL& script_url,
+ bool pause_after_download,
const std::vector<int>& possible_process_ids,
const StatusCallback& callback) {
if (!context_) {
@@ -115,7 +116,8 @@ void EmbeddedWorkerInstance::Start(int64 service_worker_version_id,
params->scope = scope;
params->script_url = script_url;
params->worker_devtools_agent_route_id = MSG_ROUTING_NONE;
- params->pause_on_start = false;
+ params->pause_after_download = pause_after_download;
+ params->wait_for_debugger = false;
context_->process_manager()->AllocateWorkerProcess(
embedded_worker_id_,
SortProcesses(possible_process_ids),
@@ -136,6 +138,13 @@ ServiceWorkerStatusCode EmbeddedWorkerInstance::Stop() {
return status;
}
+void EmbeddedWorkerInstance::ResumeAfterDownload() {
+ DCHECK_EQ(STARTING, status_);
+ registry_->Send(
+ process_id_,
+ new EmbeddedWorkerMsg_ResumeAfterDownload(embedded_worker_id_));
+}
+
ServiceWorkerStatusCode EmbeddedWorkerInstance::SendMessage(
const IPC::Message& message) {
DCHECK(status_ == RUNNING);
@@ -225,10 +234,10 @@ void EmbeddedWorkerInstance::SendStartWorker(
scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
const StatusCallback& callback,
int worker_devtools_agent_route_id,
- bool pause_on_start) {
+ bool wait_for_debugger) {
worker_devtools_agent_route_id_ = worker_devtools_agent_route_id;
params->worker_devtools_agent_route_id = worker_devtools_agent_route_id;
- params->pause_on_start = pause_on_start;
+ params->wait_for_debugger = wait_for_debugger;
registry_->SendStartWorker(params.Pass(), callback, process_id_);
}
@@ -262,6 +271,14 @@ void EmbeddedWorkerInstance::OnStopped() {
FOR_EACH_OBSERVER(Listener, listener_list_, OnStopped());
}
+void EmbeddedWorkerInstance::OnPausedAfterDownload() {
+ // Stop can be requested before getting this far.
+ if (status_ == STOPPING)
+ return;
+ DCHECK(status_ == STARTING);
+ FOR_EACH_OBSERVER(Listener, listener_list_, OnPausedAfterDownload());
+}
+
bool EmbeddedWorkerInstance::OnMessageReceived(const IPC::Message& message) {
ListenerList::Iterator it(listener_list_);
while (Listener* listener = it.GetNext()) {
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h
index 9e404ff..3b2d51d 100644
--- a/content/browser/service_worker/embedded_worker_instance.h
+++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -48,8 +48,9 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
class Listener {
public:
virtual ~Listener() {}
- virtual void OnStarted() = 0;
- virtual void OnStopped() = 0;
+ virtual void OnStarted() {}
+ virtual void OnStopped() {}
+ virtual void OnPausedAfterDownload() {}
virtual void OnReportException(const base::string16& error_message,
int line_number,
int column_number,
@@ -74,6 +75,7 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
void Start(int64 service_worker_version_id,
const GURL& scope,
const GURL& script_url,
+ bool pause_after_download,
const std::vector<int>& possible_process_ids,
const StatusCallback& callback);
@@ -87,6 +89,8 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
// It is invalid to call this while the worker is not in RUNNING status.
ServiceWorkerStatusCode SendMessage(const IPC::Message& message);
+ void ResumeAfterDownload();
+
// Add or remove |process_id| to the internal process set where this
// worker can be started.
void AddProcessReference(int process_id);
@@ -136,7 +140,7 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
void SendStartWorker(scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
const StatusCallback& callback,
int worker_devtools_agent_route_id,
- bool pause_on_start);
+ bool wait_for_debugger);
// Called back from Registry when the worker instance has ack'ed that
// it finished loading the script.
@@ -152,6 +156,8 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
// This will change the internal status from STARTING to RUNNING.
void OnStarted(int thread_id);
+ void OnPausedAfterDownload();
+
// Called back from Registry when the worker instance has ack'ed that
// its WorkerGlobalScope is actually stopped in the child process.
// This will change the internal status from STARTING or RUNNING to
diff --git a/content/browser/service_worker/embedded_worker_instance_unittest.cc b/content/browser/service_worker/embedded_worker_instance_unittest.cc
index d14ccd2..45de97e 100644
--- a/content/browser/service_worker/embedded_worker_instance_unittest.cc
+++ b/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -74,6 +74,7 @@ TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) {
service_worker_version_id,
scope,
url,
+ false,
std::vector<int>(),
base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
run_loop.Run();
@@ -118,6 +119,7 @@ TEST_F(EmbeddedWorkerInstanceTest, InstanceDestroyedBeforeStartFinishes) {
service_worker_version_id,
scope,
url,
+ false,
available_process,
base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
// But destroy it before it gets a chance to complete.
diff --git a/content/browser/service_worker/embedded_worker_registry.cc b/content/browser/service_worker/embedded_worker_registry.cc
index 74e6ab3..fa62c477 100644
--- a/content/browser/service_worker/embedded_worker_registry.cc
+++ b/content/browser/service_worker/embedded_worker_registry.cc
@@ -118,6 +118,20 @@ void EmbeddedWorkerRegistry::OnWorkerStopped(
found->second->OnStopped();
}
+void EmbeddedWorkerRegistry::OnPausedAfterDownload(
+ int process_id, int embedded_worker_id) {
+ WorkerInstanceMap::iterator found = worker_map_.find(embedded_worker_id);
+ if (found == worker_map_.end()) {
+ LOG(ERROR) << "Worker " << embedded_worker_id << " not registered";
+ return;
+ }
+ if (found->second->process_id() != process_id) {
+ LOG(ERROR) << "Incorrect embedded_worker_id";
+ return;
+ }
+ found->second->OnPausedAfterDownload();
+}
+
void EmbeddedWorkerRegistry::OnReportException(
int embedded_worker_id,
const base::string16& error_message,
diff --git a/content/browser/service_worker/embedded_worker_registry.h b/content/browser/service_worker/embedded_worker_registry.h
index ca8429b..e5cdf97 100644
--- a/content/browser/service_worker/embedded_worker_registry.h
+++ b/content/browser/service_worker/embedded_worker_registry.h
@@ -65,6 +65,7 @@ class CONTENT_EXPORT EmbeddedWorkerRegistry
void OnWorkerScriptLoadFailed(int process_id, int embedded_worker_id);
void OnWorkerStarted(int process_id, int thread_id, int embedded_worker_id);
void OnWorkerStopped(int process_id, int embedded_worker_id);
+ void OnPausedAfterDownload(int process_id, int embedded_worker_id);
void OnReportException(int embedded_worker_id,
const base::string16& error_message,
int line_number,
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc
index 8dc32a8..649040b0 100644
--- a/content/browser/service_worker/service_worker_browsertest.cc
+++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -165,7 +165,8 @@ class EmbeddedWorkerBrowserTest : public ServiceWorkerBrowserTest,
typedef EmbeddedWorkerBrowserTest self;
EmbeddedWorkerBrowserTest()
- : last_worker_status_(EmbeddedWorkerInstance::STOPPED) {}
+ : last_worker_status_(EmbeddedWorkerInstance::STOPPED),
+ pause_mode_(DONT_PAUSE) {}
virtual ~EmbeddedWorkerBrowserTest() {}
virtual void TearDownOnIOThread() OVERRIDE {
@@ -194,6 +195,7 @@ class EmbeddedWorkerBrowserTest : public ServiceWorkerBrowserTest,
service_worker_version_id,
scope,
script_url,
+ pause_mode_ != DONT_PAUSE,
processes,
base::Bind(&EmbeddedWorkerBrowserTest::StartOnIOThread2, this));
}
@@ -234,6 +236,14 @@ class EmbeddedWorkerBrowserTest : public ServiceWorkerBrowserTest,
last_worker_status_ = worker_->status();
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, done_closure_);
}
+ virtual void OnPausedAfterDownload() OVERRIDE {
+ if (pause_mode_ == PAUSE_THEN_RESUME)
+ worker_->ResumeAfterDownload();
+ else if (pause_mode_ == PAUSE_THEN_STOP)
+ worker_->Stop();
+ else
+ ASSERT_TRUE(false);
+ }
virtual void OnReportException(const base::string16& error_message,
int line_number,
int column_number,
@@ -250,6 +260,12 @@ class EmbeddedWorkerBrowserTest : public ServiceWorkerBrowserTest,
scoped_ptr<EmbeddedWorkerInstance> worker_;
EmbeddedWorkerInstance::Status last_worker_status_;
+ enum {
+ DONT_PAUSE,
+ PAUSE_THEN_RESUME,
+ PAUSE_THEN_STOP,
+ } pause_mode_;
+
// Called by EmbeddedWorkerInstance::Observer overrides so that
// test code can wait for the worker status notifications.
base::Closure done_closure_;
@@ -428,6 +444,28 @@ IN_PROC_BROWSER_TEST_F(EmbeddedWorkerBrowserTest, StartAndStop) {
ASSERT_EQ(EmbeddedWorkerInstance::STOPPED, last_worker_status_);
}
+IN_PROC_BROWSER_TEST_F(EmbeddedWorkerBrowserTest, StartPaused_ThenResume) {
+ pause_mode_ = PAUSE_THEN_RESUME;
+ base::RunLoop start_run_loop;
+ done_closure_ = start_run_loop.QuitClosure();
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&self::StartOnIOThread, this));
+ start_run_loop.Run();
+ ASSERT_EQ(EmbeddedWorkerInstance::RUNNING, last_worker_status_);
+}
+
+// TODO(michaeln): Enable after the blink side is fixed.
+IN_PROC_BROWSER_TEST_F(EmbeddedWorkerBrowserTest,
+ DISABLED_StartPaused_ThenStop) {
+ pause_mode_ = PAUSE_THEN_STOP;
+ base::RunLoop start_run_loop;
+ done_closure_ = start_run_loop.QuitClosure();
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&self::StartOnIOThread, this));
+ start_run_loop.Run();
+ ASSERT_EQ(EmbeddedWorkerInstance::STOPPED, last_worker_status_);
+}
+
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, StartAndStop) {
RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, this,
"/service_worker/worker.js"));
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc
index adba272..7a75e2d 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -124,6 +124,8 @@ bool ServiceWorkerDispatcherHost::OnMessageReceived(
OnWorkerStarted)
IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStopped,
OnWorkerStopped)
+ IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_DidPauseAfterDownload,
+ OnPausedAfterDownload)
IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportException,
OnReportException)
IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_ReportConsoleMessage,
@@ -383,6 +385,14 @@ void ServiceWorkerDispatcherHost::OnWorkerStopped(int embedded_worker_id) {
registry->OnWorkerStopped(render_process_id_, embedded_worker_id);
}
+void ServiceWorkerDispatcherHost::OnPausedAfterDownload(
+ int embedded_worker_id) {
+ if (!GetContext())
+ return;
+ GetContext()->embedded_worker_registry()->OnPausedAfterDownload(
+ render_process_id_, embedded_worker_id);
+}
+
void ServiceWorkerDispatcherHost::OnReportException(
int embedded_worker_id,
const base::string16& error_message,
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.h b/content/browser/service_worker/service_worker_dispatcher_host.h
index b269311..8a08d65 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.h
+++ b/content/browser/service_worker/service_worker_dispatcher_host.h
@@ -76,6 +76,7 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
void OnWorkerStarted(int thread_id,
int embedded_worker_id);
void OnWorkerStopped(int embedded_worker_id);
+ void OnPausedAfterDownload(int embedded_worker_id);
void OnReportException(int embedded_worker_id,
const base::string16& error_message,
int line_number,
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc
index 098b6b3..c4dc0bd 100644
--- a/content/browser/service_worker/service_worker_register_job.cc
+++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -237,10 +237,13 @@ void ServiceWorkerRegisterJob::UpdateAndContinue(
set_pending_version(new ServiceWorkerVersion(
registration(), context_->storage()->NewVersionId(), context_));
- // TODO(michaeln): Start the worker into a paused state where the
- // script resource is downloaded but not yet evaluated.
+ // TODO(michaeln): Pause after downloading when performing an update.
+ bool pause_after_download = false;
+ if (pause_after_download)
+ pending_version()->embedded_worker()->AddListener(this);
pending_version()->StartWorkerWithCandidateProcesses(
pending_process_ids_,
+ pause_after_download,
base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished,
weak_factory_.GetWeakPtr()));
}
@@ -254,12 +257,6 @@ void ServiceWorkerRegisterJob::OnStartWorkerFinished(
return;
}
- // TODO(michaeln): Compare the old and new script.
- // If different unpause the worker and continue with
- // the job. If the same ResolvePromise with the current
- // version and complete the job, throwing away the new version
- // since there's nothing new.
-
// "Resolve promise with serviceWorker."
// Although the spec doesn't set waitingWorker until after resolving the
// promise, our system's resolving works by passing ServiceWorkerRegistration
@@ -396,6 +393,8 @@ void ServiceWorkerRegisterJob::CompleteInternal(
context_->storage()->NotifyDoneInstallingRegistration(
registration(), pending_version(), status);
}
+ if (pending_version())
+ pending_version()->embedded_worker()->RemoveListener(this);
}
void ServiceWorkerRegisterJob::ResolvePromise(
@@ -415,6 +414,20 @@ void ServiceWorkerRegisterJob::ResolvePromise(
callbacks_.clear();
}
+void ServiceWorkerRegisterJob::OnPausedAfterDownload() {
+ // TODO(michaeln): Compare the old and new script.
+ // If different unpause the worker and continue with
+ // the job. If the same ResolvePromise with the current
+ // version and complete the job, throwing away the new version
+ // since there's nothing new.
+ pending_version()->embedded_worker()->RemoveListener(this);
+ pending_version()->embedded_worker()->ResumeAfterDownload();
+}
+
+bool ServiceWorkerRegisterJob::OnMessageReceived(const IPC::Message& message) {
+ return false;
+}
+
// static
void ServiceWorkerRegisterJob::AssociateWaitingVersionToDocuments(
base::WeakPtr<ServiceWorkerContextCore> context,
diff --git a/content/browser/service_worker/service_worker_register_job.h b/content/browser/service_worker/service_worker_register_job.h
index db10fa6..4ca1162 100644
--- a/content/browser/service_worker/service_worker_register_job.h
+++ b/content/browser/service_worker/service_worker_register_job.h
@@ -8,6 +8,7 @@
#include <vector>
#include "base/memory/weak_ptr.h"
+#include "content/browser/service_worker/embedded_worker_instance.h"
#include "content/browser/service_worker/service_worker_register_job_base.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/common/service_worker/service_worker_status_code.h"
@@ -31,7 +32,9 @@ class ServiceWorkerStorage;
// - firing the 'activate' event at the ServiceWorkerVersion
// - waiting for older ServiceWorkerVersions to deactivate
// - designating the new version to be the 'active' version
-class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase {
+class ServiceWorkerRegisterJob
+ : public ServiceWorkerRegisterJobBase,
+ public EmbeddedWorkerInstance::Listener {
public:
typedef base::Callback<void(ServiceWorkerStatusCode status,
ServiceWorkerRegistration* registration,
@@ -111,6 +114,10 @@ class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase {
ServiceWorkerRegistration* registration,
ServiceWorkerVersion* version);
+ // EmbeddedWorkerInstance::Listener override of OnPausedAfterDownload.
+ virtual void OnPausedAfterDownload() OVERRIDE;
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+
// Associates a waiting version to documents matched with a scope of the
// version.
CONTENT_EXPORT static void AssociateWaitingVersionToDocuments(
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 50f24df..b37c796 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -149,11 +149,12 @@ ServiceWorkerVersionInfo ServiceWorkerVersion::GetInfo() {
}
void ServiceWorkerVersion::StartWorker(const StatusCallback& callback) {
- StartWorkerWithCandidateProcesses(std::vector<int>(), callback);
+ StartWorkerWithCandidateProcesses(std::vector<int>(), false, callback);
}
void ServiceWorkerVersion::StartWorkerWithCandidateProcesses(
const std::vector<int>& possible_process_ids,
+ bool pause_after_download,
const StatusCallback& callback) {
switch (running_status()) {
case RUNNING:
@@ -170,6 +171,7 @@ void ServiceWorkerVersion::StartWorkerWithCandidateProcesses(
version_id_,
scope_,
script_url_,
+ pause_after_download,
possible_process_ids,
base::Bind(&ServiceWorkerVersion::RunStartWorkerCallbacksOnError,
weak_factory_.GetWeakPtr()));
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 0c7bda5..432be47 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -125,6 +125,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
// This returns OK (success) if the worker is already running.
void StartWorkerWithCandidateProcesses(
const std::vector<int>& potential_process_ids,
+ bool pause_after_download,
const StatusCallback& callback);
// Starts an embedded worker for this version.
diff --git a/content/common/service_worker/embedded_worker_messages.h b/content/common/service_worker/embedded_worker_messages.h
index df5cf69..c8f2fa2 100644
--- a/content/common/service_worker/embedded_worker_messages.h
+++ b/content/common/service_worker/embedded_worker_messages.h
@@ -23,7 +23,8 @@ IPC_STRUCT_BEGIN(EmbeddedWorkerMsg_StartWorker_Params)
IPC_STRUCT_MEMBER(GURL, scope)
IPC_STRUCT_MEMBER(GURL, script_url)
IPC_STRUCT_MEMBER(int, worker_devtools_agent_route_id)
- IPC_STRUCT_MEMBER(bool, pause_on_start)
+ IPC_STRUCT_MEMBER(bool, pause_after_download)
+ IPC_STRUCT_MEMBER(bool, wait_for_debugger)
IPC_STRUCT_END()
// Parameters structure for EmbeddedWorkerHostMsg_ReportConsoleMessage.
@@ -41,10 +42,20 @@ IPC_STRUCT_END()
IPC_MESSAGE_CONTROL1(EmbeddedWorkerMsg_StartWorker,
EmbeddedWorkerMsg_StartWorker_Params /* params */)
+// Browser -> Renderer message to resume a worker that has been started
+// with the pause_after_download option.
+IPC_MESSAGE_CONTROL1(EmbeddedWorkerMsg_ResumeAfterDownload,
+ int /* embedded_worker_id */)
+
// Browser -> Renderer message to stop (terminate) the embedded worker.
IPC_MESSAGE_CONTROL1(EmbeddedWorkerMsg_StopWorker,
int /* embedded_worker_id */)
+// Renderer -> Browser message to indicate that the worker script has been
+// downloaded and the embedded worker is in paused state.
+IPC_MESSAGE_CONTROL1(EmbeddedWorkerHostMsg_DidPauseAfterDownload,
+ int /* embedded_worker_id */)
+
// Renderer -> Browser message to indicate that the worker has loadedd the
// script.
IPC_MESSAGE_CONTROL1(EmbeddedWorkerHostMsg_WorkerScriptLoaded,
diff --git a/content/renderer/service_worker/embedded_worker_context_client.cc b/content/renderer/service_worker/embedded_worker_context_client.cc
index ea4072d..3642eff 100644
--- a/content/renderer/service_worker/embedded_worker_context_client.cc
+++ b/content/renderer/service_worker/embedded_worker_context_client.cc
@@ -120,6 +120,10 @@ blink::WebURL EmbeddedWorkerContextClient::scope() const {
return service_worker_scope_;
}
+void EmbeddedWorkerContextClient::didPauseAfterDownload() {
+ Send(new EmbeddedWorkerHostMsg_DidPauseAfterDownload(embedded_worker_id_));
+}
+
void EmbeddedWorkerContextClient::getClients(
blink::WebServiceWorkerClientsCallbacks* callbacks) {
DCHECK(script_context_);
diff --git a/content/renderer/service_worker/embedded_worker_context_client.h b/content/renderer/service_worker/embedded_worker_context_client.h
index 7d18ec5..3fa6973 100644
--- a/content/renderer/service_worker/embedded_worker_context_client.h
+++ b/content/renderer/service_worker/embedded_worker_context_client.h
@@ -66,6 +66,7 @@ class EmbeddedWorkerContextClient
// WebServiceWorkerContextClient overrides, some of them are just dispatched
// on to script_context_.
virtual blink::WebURL scope() const;
+ virtual void didPauseAfterDownload();
virtual void getClients(blink::WebServiceWorkerClientsCallbacks*);
virtual void workerContextFailedToStart();
virtual void workerContextStarted(blink::WebServiceWorkerContextProxy* proxy);
diff --git a/content/renderer/service_worker/embedded_worker_dispatcher.cc b/content/renderer/service_worker/embedded_worker_dispatcher.cc
index 15ff76a4..9630f3a 100644
--- a/content/renderer/service_worker/embedded_worker_dispatcher.cc
+++ b/content/renderer/service_worker/embedded_worker_dispatcher.cc
@@ -52,6 +52,8 @@ bool EmbeddedWorkerDispatcher::OnMessageReceived(
IPC_BEGIN_MESSAGE_MAP(EmbeddedWorkerDispatcher, message)
IPC_MESSAGE_HANDLER(EmbeddedWorkerMsg_StartWorker, OnStartWorker)
IPC_MESSAGE_HANDLER(EmbeddedWorkerMsg_StopWorker, OnStopWorker)
+ IPC_MESSAGE_HANDLER(EmbeddedWorkerMsg_ResumeAfterDownload,
+ OnResumeAfterDownload)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -82,9 +84,21 @@ void EmbeddedWorkerDispatcher::OnStartWorker(
blink::WebEmbeddedWorkerStartData start_data;
start_data.scriptURL = params.script_url;
start_data.userAgent = base::UTF8ToUTF16(GetContentClient()->GetUserAgent());
+ start_data.pauseAfterDownloadMode =
+ params.pause_after_download ?
+ blink::WebEmbeddedWorkerStartData::PauseAfterDownload :
+ blink::WebEmbeddedWorkerStartData::DontPauseAfterDownload;
+ start_data.waitForDebuggerMode =
+ params.wait_for_debugger ?
+ blink::WebEmbeddedWorkerStartData::WaitForDebugger :
+ blink::WebEmbeddedWorkerStartData::DontWaitForDebugger;
+
+ // TODO(michaeln): delete setting this deprecated member once blink
+ // stops reading it.
start_data.startMode =
- params.pause_on_start ? blink::WebEmbeddedWorkerStartModePauseOnStart
- : blink::WebEmbeddedWorkerStartModeDontPauseOnStart;
+ params.wait_for_debugger ?
+ blink::WebEmbeddedWorkerStartModePauseOnStart :
+ blink::WebEmbeddedWorkerStartModeDontPauseOnStart;
wrapper->worker()->startWorkerContext(start_data);
workers_.AddWithID(wrapper.release(), params.embedded_worker_id);
@@ -103,4 +117,13 @@ void EmbeddedWorkerDispatcher::OnStopWorker(int embedded_worker_id) {
wrapper->worker()->terminateWorkerContext();
}
+void EmbeddedWorkerDispatcher::OnResumeAfterDownload(int embedded_worker_id) {
+ WorkerWrapper* wrapper = workers_.Lookup(embedded_worker_id);
+ if (!wrapper) {
+ LOG(WARNING) << "Got OnResumeAfterDownload for nonexistent worker";
+ return;
+ }
+ wrapper->worker()->resumeAfterDownload();
+}
+
} // namespace content
diff --git a/content/renderer/service_worker/embedded_worker_dispatcher.h b/content/renderer/service_worker/embedded_worker_dispatcher.h
index 4f3434f..104ebfa 100644
--- a/content/renderer/service_worker/embedded_worker_dispatcher.h
+++ b/content/renderer/service_worker/embedded_worker_dispatcher.h
@@ -35,6 +35,7 @@ class EmbeddedWorkerDispatcher : public IPC::Listener {
void OnStartWorker(const EmbeddedWorkerMsg_StartWorker_Params& params);
void OnStopWorker(int embedded_worker_id);
+ void OnResumeAfterDownload(int embedded_worker_id);
IDMap<WorkerWrapper, IDMapOwnPointer> workers_;
base::WeakPtrFactory<EmbeddedWorkerDispatcher> weak_factory_;