| Index: content/browser/service_worker/service_worker_version.cc
|
| diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
|
| index 9504befa051be62a2107d6d13ce6525445130254..4a15f57992f0110ca6b8dda24ac06673505a1a38 100644
|
| --- a/content/browser/service_worker/service_worker_version.cc
|
| +++ b/content/browser/service_worker/service_worker_version.cc
|
| @@ -22,6 +22,7 @@
|
| #include "content/browser/service_worker/service_worker_metrics.h"
|
| #include "content/browser/service_worker/service_worker_registration.h"
|
| #include "content/browser/service_worker/service_worker_utils.h"
|
| +#include "content/browser/service_worker/stashed_port_manager.h"
|
| #include "content/browser/storage_partition_impl.h"
|
| #include "content/common/service_worker/service_worker_messages.h"
|
| #include "content/public/browser/browser_thread.h"
|
| @@ -161,6 +162,12 @@ void RunErrorCrossOriginConnectCallback(
|
| callback.Run(status, false /* accept_connection */);
|
| }
|
|
|
| +void RunErrorSendStashedPortsCallback(
|
| + const ServiceWorkerVersion::SendStashedPortsCallback& callback,
|
| + ServiceWorkerStatusCode status) {
|
| + callback.Run(status, std::vector<int>());
|
| +}
|
| +
|
| using WindowOpenedCallback = base::Callback<void(int, int)>;
|
|
|
| // The WindowOpenedObserver class is a WebContentsObserver that will wait for a
|
| @@ -361,6 +368,21 @@ bool IsInstalled(ServiceWorkerVersion::Status status) {
|
| return false;
|
| }
|
|
|
| +scoped_refptr<StashedPortManager> GetStashedPortManagerOnUIThread(
|
| + const scoped_refptr<ServiceWorkerContextWrapper>& context_wrapper) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + return context_wrapper->storage_partition()->GetStashedPortManager();
|
| +}
|
| +
|
| +void StashPortImpl(
|
| + const scoped_refptr<ServiceWorkerVersion> service_worker,
|
| + int message_port_id,
|
| + const base::string16& name,
|
| + const scoped_refptr<StashedPortManager> stashed_port_manager) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + stashed_port_manager->AddPort(service_worker.get(), message_port_id, name);
|
| +}
|
| +
|
| } // namespace
|
|
|
| const int ServiceWorkerVersion::kStartWorkerTimeoutMinutes = 5;
|
| @@ -792,6 +814,32 @@ void ServiceWorkerVersion::DispatchCrossOriginMessageEvent(
|
| RunSoon(base::Bind(callback, status));
|
| }
|
|
|
| +void ServiceWorkerVersion::SendStashedMessagePorts(
|
| + const std::vector<TransferredMessagePort>& stashed_message_ports,
|
| + const std::vector<base::string16>& port_names,
|
| + const SendStashedPortsCallback& callback) {
|
| + if (running_status() != RUNNING) {
|
| + // Schedule calling this method after starting the worker.
|
| + StartWorker(base::Bind(
|
| + &RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(),
|
| + base::Bind(&RunErrorSendStashedPortsCallback, callback),
|
| + base::Bind(&self::SendStashedMessagePorts, weak_factory_.GetWeakPtr(),
|
| + stashed_message_ports, port_names, callback)));
|
| + return;
|
| + }
|
| +
|
| + MessagePortMessageFilter* filter =
|
| + embedded_worker_->message_port_message_filter();
|
| + std::vector<int> new_routing_ids(stashed_message_ports.size());
|
| + for (size_t i = 0; i < stashed_message_ports.size(); ++i)
|
| + new_routing_ids[i] = filter->GetNextRoutingID();
|
| +
|
| + ServiceWorkerStatusCode status =
|
| + embedded_worker_->SendMessage(ServiceWorkerMsg_SendStashedMessagePorts(
|
| + stashed_message_ports, new_routing_ids, port_names));
|
| + RunSoon(base::Bind(callback, status, new_routing_ids));
|
| +}
|
| +
|
| void ServiceWorkerVersion::AddControllee(
|
| ServiceWorkerProviderHost* provider_host) {
|
| const std::string& uuid = provider_host->client_uuid();
|
| @@ -1046,6 +1094,8 @@ bool ServiceWorkerVersion::OnMessageReceived(const IPC::Message& message) {
|
| IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClaimClients,
|
| OnClaimClients)
|
| IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_Pong, OnPongFromWorker)
|
| + IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_StashMessagePort,
|
| + OnStashMessagePort)
|
| IPC_MESSAGE_UNHANDLED(handled = false)
|
| IPC_END_MESSAGE_MAP()
|
| return handled;
|
| @@ -1521,6 +1571,26 @@ void ServiceWorkerVersion::OnPongFromWorker() {
|
| ClearTick(&ping_time_);
|
| }
|
|
|
| +void ServiceWorkerVersion::OnStashMessagePort(int message_port_id,
|
| + const base::string16& name) {
|
| + // Just abort if we are shutting down.
|
| + if (!context_)
|
| + return;
|
| +
|
| + ServiceWorkerRegistration* registration =
|
| + context_->GetLiveRegistration(registration_id_);
|
| + if (!registration)
|
| + return;
|
| +
|
| + // TODO(mek): Figure out a way to avoid this round-trip through the UI thread.
|
| + BrowserThread::PostTaskAndReplyWithResult(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&GetStashedPortManagerOnUIThread,
|
| + make_scoped_refptr(context_->wrapper())),
|
| + base::Bind(&StashPortImpl, make_scoped_refptr(this), message_port_id,
|
| + name));
|
| +}
|
| +
|
| void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker(
|
| bool pause_after_download,
|
| const StatusCallback& callback,
|
|
|