Skip to content

Commit

Permalink
Implement ServiceWorkerClient attributes [2/3]
Browse files Browse the repository at this point in the history
Patch dependency:
[1] Blink: https://crrev.com/783663002/
[2] Chromium: https://crrev.com/771103002/ (THIS PATCH)
[3] Blink: https://crrev.com/778703004/

Spec: http://slightlyoff.github.io/ServiceWorker/spec/service_worker/#service-worker-client

BUG=436335,437152

Review URL: https://codereview.chromium.org/771103002

Cr-Commit-Position: refs/heads/master@{#307852}
  • Loading branch information
irori authored and Commit bot committed Dec 11, 2014
1 parent 78e4cdc commit 2ff1341
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,13 @@ void ServiceWorkerProviderHost::Focus(const FocusCallback& callback) {
callback));
}

void ServiceWorkerProviderHost::GetClientInfo(
int embedded_worker_id,
int request_id) {
dispatcher_host_->Send(new ServiceWorkerMsg_GetClientInfo(
kDocumentMainThreadId, embedded_worker_id, request_id, provider_id()));
}

void ServiceWorkerProviderHost::AddScopedProcessReferenceToPattern(
const GURL& pattern) {
associated_patterns_.push_back(pattern);
Expand Down
3 changes: 3 additions & 0 deletions content/browser/service_worker/service_worker_provider_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// focusing action was successful.
void Focus(const FocusCallback& callback);

// Asks the renderer to send back the document information.
void GetClientInfo(int embedded_worker_id, int request_id);

// Adds reference of this host's process to the |pattern|, the reference will
// be removed in destructor.
void AddScopedProcessReferenceToPattern(const GURL& pattern);
Expand Down
105 changes: 99 additions & 6 deletions content/browser/service_worker/service_worker_version.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -23,6 +24,61 @@ 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),
pending_requests_(pending_requests) {}
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,
const scoped_refptr<GetClientDocumentsCallback>& callback)
: client_id_(client_id),
callback_(callback) {}

void OnSuccess(ServiceWorkerVersion* version,
const ServiceWorkerClientInfo& info) {
callback_->AddClientInfo(client_id_, info);
callback_->DecrementPendingRequests(version);
}
void OnError(ServiceWorkerVersion* version) {
callback_->DecrementPendingRequests(version);
}

private:
int client_id_;
scoped_refptr<GetClientDocumentsCallback> callback_;

DISALLOW_COPY_AND_ASSIGN(GetClientInfoCallback);
};

namespace {

// Default delay for scheduled stop.
Expand Down Expand Up @@ -581,6 +637,8 @@ void ServiceWorkerVersion::OnStopped(
RunIDMapCallbacks(&geofencing_callbacks_,
SERVICE_WORKER_ERROR_FAILED);

get_client_info_callbacks_.Clear();

FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this));

// There should be no more communication from/to a stopped worker. Deleting
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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(
Expand Down
7 changes: 7 additions & 0 deletions content/browser/service_worker/service_worker_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,9 @@ class CONTENT_EXPORT ServiceWorkerVersion
bool is_doomed() const { return is_doomed_; }

private:
class GetClientDocumentsCallback;
class GetClientInfoCallback;

friend class base::RefCounted<ServiceWorkerVersion>;
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerControlleeRequestHandlerTest,
ActivateWaitingVersion);
Expand Down Expand Up @@ -290,6 +293,9 @@ class CONTENT_EXPORT ServiceWorkerVersion

// Message handlers.
void OnGetClientDocuments(int request_id);
void OnGetClientInfoSuccess(int request_id,
const ServiceWorkerClientInfo& info);
void OnGetClientInfoError(int request_id);
void OnActivateEventFinished(int request_id,
blink::WebServiceWorkerEventResult result);
void OnInstallEventFinished(int request_id,
Expand Down Expand Up @@ -330,6 +336,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
IDMap<StatusCallback, IDMapOwnPointer> notification_click_callbacks_;
IDMap<StatusCallback, IDMapOwnPointer> push_callbacks_;
IDMap<StatusCallback, IDMapOwnPointer> geofencing_callbacks_;
IDMap<GetClientInfoCallback, IDMapOwnPointer> get_client_info_callbacks_;

ControlleeMap controllee_map_;
ControlleeByIDMap controllee_by_id_;
Expand Down
27 changes: 27 additions & 0 deletions content/child/service_worker/service_worker_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "content/child/webmessageportchannel_impl.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "content/public/common/url_utils.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerClientsInfo.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerProviderClient.h"
#include "third_party/WebKit/public/web/WebSecurityOrigin.h"

Expand Down Expand Up @@ -79,6 +80,8 @@ void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) {
OnSetControllerServiceWorker)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument,
OnPostMessage)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_GetClientInfo,
OnGetClientInfo)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
DCHECK(handled) << "Unhandled message:" << msg.type();
Expand Down Expand Up @@ -688,6 +691,30 @@ void ServiceWorkerDispatcher::OnPostMessage(
found->second->dispatchMessageEvent(message, ports);
}

void ServiceWorkerDispatcher::OnGetClientInfo(int thread_id,
int embedded_worker_id,
int request_id,
int provider_id) {
blink::WebServiceWorkerClientInfo info;
ScriptClientMap::iterator found = script_clients_.find(provider_id);
// TODO(ksakamoto): Could we track these values in the browser side? Except
// for |isFocused|, it would be pretty easy.
if (found != script_clients_.end() && found->second->getClientInfo(&info)) {
ServiceWorkerClientInfo result;
result.client_id = info.clientID;
result.visibility_state = info.visibilityState.utf8();
result.is_focused = info.isFocused;
result.url = info.url;
result.frame_type = static_cast<RequestContextFrameType>(info.frameType);

thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetClientInfoSuccess(
embedded_worker_id, request_id, result));
} else {
thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetClientInfoError(
embedded_worker_id, request_id));
}
}

void ServiceWorkerDispatcher::AddServiceWorker(
int handle_id, WebServiceWorkerImpl* worker) {
DCHECK(!ContainsKey(service_workers_, handle_id));
Expand Down
4 changes: 4 additions & 0 deletions content/child/service_worker/service_worker_dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer {
const base::string16& message,
const std::vector<int>& sent_message_port_ids,
const std::vector<int>& new_routing_ids);
void OnGetClientInfo(int thread_id,
int embedded_worker_id,
int request_id,
int provider_id);

void SetInstallingServiceWorker(
int provider_id,
Expand Down
26 changes: 25 additions & 1 deletion content/common/service_worker/service_worker_messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerVersionAttributes)
IPC_STRUCT_TRAITS_MEMBER(active)
IPC_STRUCT_TRAITS_END()

IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerClientInfo)
IPC_STRUCT_TRAITS_MEMBER(client_id)
IPC_STRUCT_TRAITS_MEMBER(visibility_state)
IPC_STRUCT_TRAITS_MEMBER(is_focused)
IPC_STRUCT_TRAITS_MEMBER(url)
IPC_STRUCT_TRAITS_MEMBER(frame_type)
IPC_STRUCT_TRAITS_END()

IPC_ENUM_TRAITS_MAX_VALUE(
blink::WebServiceWorkerCacheError,
blink::WebServiceWorkerCacheErrorLast)
Expand Down Expand Up @@ -216,6 +224,15 @@ IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_FocusClient,
int /* request_id */,
int /* client_id */)

// Response to ServiceWorkerMsg_GetClientInfo.
IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_GetClientInfoSuccess,
int /* request_id */,
content::ServiceWorkerClientInfo)

// Response to ServiceWorkerMsg_GetClientInfo.
IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_GetClientInfoError,
int /* request_id */)

// CacheStorage operations in the browser.
IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_CacheStorageHas,
int /* request_id */,
Expand Down Expand Up @@ -365,6 +382,13 @@ IPC_MESSAGE_CONTROL5(ServiceWorkerMsg_MessageToDocument,
std::vector<int> /* sent_message_port_ids */,
std::vector<int> /* new_routing_ids */)

// Sent to client documents to request document properties.
IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_GetClientInfo,
int /* thread_id */,
int /* embedded_worker_id */,
int /* request_id */,
int /* provider_id */)

// Sent via EmbeddedWorker to dispatch events.
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_InstallEvent,
int /* request_id */,
Expand Down Expand Up @@ -396,7 +420,7 @@ IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_MessageToWorker,
// Sent via EmbeddedWorker as a response of GetClientDocuments.
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_DidGetClientDocuments,
int /* request_id */,
std::vector<int> /* client_ids */)
std::vector<content::ServiceWorkerClientInfo>)

// Sent via EmbeddedWorker as a response of FocusClient.
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_FocusClientResponse,
Expand Down
8 changes: 8 additions & 0 deletions content/common/service_worker/service_worker_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,14 @@ class ChangedVersionAttributesMask {
int changed_;
};

struct ServiceWorkerClientInfo {
int client_id;
std::string visibility_state;
bool is_focused;
GURL url;
RequestContextFrameType frame_type;
};

} // namespace content

#endif // CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_TYPES_H_
15 changes: 13 additions & 2 deletions content/renderer/service_worker/service_worker_script_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ void ServiceWorkerScriptContext::OnPostMessage(
}

void ServiceWorkerScriptContext::OnDidGetClientDocuments(
int request_id, const std::vector<int>& client_ids) {
int request_id, const std::vector<ServiceWorkerClientInfo>& clients) {
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerScriptContext::OnDidGetClientDocuments");
blink::WebServiceWorkerClientsCallbacks* callbacks =
Expand All @@ -338,7 +338,18 @@ void ServiceWorkerScriptContext::OnDidGetClientDocuments(
}
scoped_ptr<blink::WebServiceWorkerClientsInfo> info(
new blink::WebServiceWorkerClientsInfo);
info->clientIDs = client_ids;
blink::WebVector<blink::WebServiceWorkerClientInfo> convertedClients(
clients.size());
for (size_t i = 0; i < clients.size(); ++i) {
convertedClients[i].clientID = clients[i].client_id;
convertedClients[i].visibilityState =
blink::WebString::fromUTF8(clients[i].visibility_state);
convertedClients[i].isFocused = clients[i].is_focused;
convertedClients[i].url = clients[i].url;
convertedClients[i].frameType =
static_cast<blink::WebURLRequest::FrameType>(clients[i].frame_type);
}
info->clients.swap(convertedClients);
callbacks->onSuccess(info.release());
pending_clients_callbacks_.Remove(request_id);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class ServiceWorkerScriptContext {
const std::vector<int>& sent_message_port_ids,
const std::vector<int>& new_routing_ids);
void OnDidGetClientDocuments(
int request_id, const std::vector<int>& client_ids);
int request_id, const std::vector<ServiceWorkerClientInfo>& clients);
void OnFocusClientResponse(int request_id, bool result);

scoped_ptr<ServiceWorkerCacheStorageDispatcher> cache_storage_dispatcher_;
Expand Down

0 comments on commit 2ff1341

Please sign in to comment.