Chromium Code Reviews| 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 5ad3c4ebac6480802c534e30ae416c07e893bb38..d6f567747b098ebe9c9d8f9446da1b0b53efe928 100644 |
| --- a/content/browser/service_worker/service_worker_version.cc |
| +++ b/content/browser/service_worker/service_worker_version.cc |
| @@ -5,6 +5,7 @@ |
| #include "content/browser/service_worker/service_worker_version.h" |
| #include "base/command_line.h" |
| +#include "base/memory/ref_counted.h" |
| #include "base/stl_util.h" |
| #include "base/strings/string16.h" |
| #include "content/browser/message_port_message_filter.h" |
| @@ -23,6 +24,63 @@ namespace content { |
| typedef ServiceWorkerVersion::StatusCallback StatusCallback; |
| typedef ServiceWorkerVersion::MessageCallback MessageCallback; |
| +class ServiceWorkerVersion::GetClientDocumentsCallback |
| + : public base::RefCounted<GetClientDocumentsCallback> { |
| + public: |
| + GetClientDocumentsCallback(int request_id, int pending_requests) |
| + : request_id_(request_id) |
|
dcheng
2014/12/10 20:17:12
I think this should be indented another two spaces
Kunihiko Sakamoto
2014/12/11 01:20:31
Done.
|
| + , pending_requests_(pending_requests) {} |
|
dcheng
2014/12/10 20:17:12
Chrome convention is to put the "," on the previou
Kunihiko Sakamoto
2014/12/11 01:20:31
Done.
|
| + void AddClientInfo(int client_id, const ServiceWorkerClientInfo& info) { |
| + clients_.push_back(info); |
| + clients_.back().client_id = client_id; |
| + } |
| + void DecrementPendingRequests(ServiceWorkerVersion* version) { |
| + if (--pending_requests_ > 0) |
| + return; |
| + // Don't bother if it's no longer running. |
| + if (version->running_status() == RUNNING) { |
| + version->embedded_worker_->SendMessage( |
| + ServiceWorkerMsg_DidGetClientDocuments(request_id_, clients_)); |
| + } |
| + } |
| + |
| + private: |
| + friend class base::RefCounted<GetClientDocumentsCallback>; |
| + virtual ~GetClientDocumentsCallback() {} |
| + |
| + std::vector<ServiceWorkerClientInfo> clients_; |
| + int request_id_; |
| + size_t pending_requests_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(GetClientDocumentsCallback); |
| +}; |
| + |
| +class ServiceWorkerVersion::GetClientInfoCallback { |
| + public: |
| + GetClientInfoCallback(int client_id, |
| + scoped_refptr<GetClientDocumentsCallback>& callback) |
|
dcheng
2014/12/10 20:17:12
Blink doesn't allow mutable refs so this should be
Kunihiko Sakamoto
2014/12/11 01:20:31
Done.
|
| + : client_id_(client_id) |
|
dcheng
2014/12/10 20:17:12
Ditto on indenting.
Kunihiko Sakamoto
2014/12/11 01:20:31
Done.
|
| + , callback_(callback) {} |
| + |
| + void OnSuccess(ServiceWorkerVersion* version, |
| + const ServiceWorkerClientInfo& info) { |
| + callback_->AddClientInfo(client_id_, info); |
| + callback_->DecrementPendingRequests(version); |
| + } |
| + void OnError(ServiceWorkerVersion* version) { |
| + callback_->DecrementPendingRequests(version); |
| + } |
| + void OnCancel(ServiceWorkerVersion* version) { |
| + callback_->DecrementPendingRequests(version); |
| + } |
| + |
| + private: |
| + int client_id_; |
| + scoped_refptr<GetClientDocumentsCallback> callback_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(GetClientInfoCallback); |
| +}; |
| + |
| namespace { |
| // Default delay for scheduled stop. |
| @@ -648,6 +706,10 @@ bool ServiceWorkerVersion::OnMessageReceived(const IPC::Message& message) { |
| OnPostMessageToDocument) |
| IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient, |
| OnFocusClient) |
| + IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoSuccess, |
| + OnGetClientInfoSuccess) |
| + IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_GetClientInfoError, |
| + OnGetClientInfoError) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP() |
| return handled; |
| @@ -689,19 +751,50 @@ void ServiceWorkerVersion::DispatchActivateEventAfterStartWorker( |
| } |
| void ServiceWorkerVersion::OnGetClientDocuments(int request_id) { |
| - std::vector<int> client_ids; |
| + if (controllee_by_id_.IsEmpty()) { |
| + if (running_status() == RUNNING) { |
| + embedded_worker_->SendMessage( |
| + ServiceWorkerMsg_DidGetClientDocuments(request_id, |
| + std::vector<ServiceWorkerClientInfo>())); |
| + } |
| + return; |
| + } |
| + scoped_refptr<GetClientDocumentsCallback> callback( |
| + new GetClientDocumentsCallback(request_id, controllee_by_id_.size())); |
| ControlleeByIDMap::iterator it(&controllee_by_id_); |
| TRACE_EVENT0("ServiceWorker", |
| "ServiceWorkerVersion::OnGetClientDocuments"); |
| while (!it.IsAtEnd()) { |
| - client_ids.push_back(it.GetCurrentKey()); |
| + int client_request_id = get_client_info_callbacks_.Add( |
| + new GetClientInfoCallback(it.GetCurrentKey(), callback)); |
| + it.GetCurrentValue()->GetClientInfo(embedded_worker_->embedded_worker_id(), |
| + client_request_id); |
| it.Advance(); |
| } |
| - // Don't bother if it's no longer running. |
| - if (running_status() == RUNNING) { |
| - embedded_worker_->SendMessage( |
| - ServiceWorkerMsg_DidGetClientDocuments(request_id, client_ids)); |
| +} |
| + |
| +void ServiceWorkerVersion::OnGetClientInfoSuccess( |
| + int request_id, |
| + const ServiceWorkerClientInfo& info) { |
| + GetClientInfoCallback* callback = |
| + get_client_info_callbacks_.Lookup(request_id); |
| + if (!callback) { |
| + // The callback may already have been cleared by OnStopped, just ignore. |
| + return; |
| + } |
| + callback->OnSuccess(this, info); |
| + get_client_info_callbacks_.Remove(request_id); |
| +} |
| + |
| +void ServiceWorkerVersion::OnGetClientInfoError(int request_id) { |
| + GetClientInfoCallback* callback = |
| + get_client_info_callbacks_.Lookup(request_id); |
| + if (!callback) { |
| + // The callback may already have been cleared by OnStopped, just ignore. |
| + return; |
| } |
| + callback->OnError(this); |
| + get_client_info_callbacks_.Remove(request_id); |
| } |
| void ServiceWorkerVersion::OnActivateEventFinished( |