Commit dfea9a1a authored by kinuko@chromium.org's avatar kinuko@chromium.org

Wire provider_id into scriptable API provider to start listening events for the document

- Wire provider_id to Scriptable-API ServiceWorkerProvider
- Send AddScriptClient/RemoveScriptClient message which is sent when navigator.serviceWorker is accessed (or detached)

We can use the clients information when we dispatch events to
controllee documents.

BUG=349919
TEST=will add browser tests after one more patch in blink

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@255919 0039d316-1c4b-4281-b951-d872f2087c98
parent d3e31f71
......@@ -80,6 +80,10 @@ bool ServiceWorkerDispatcherHost::OnMessageReceived(
OnProviderCreated)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderDestroyed,
OnProviderDestroyed)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_AddScriptClient,
OnAddScriptClient)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_RemoveScriptClient,
OnRemoveScriptClient)
IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStarted,
OnWorkerStarted)
IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStopped,
......@@ -175,6 +179,28 @@ void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id) {
context_->RemoveProviderHost(render_process_id_, provider_id);
}
void ServiceWorkerDispatcherHost::OnAddScriptClient(
int thread_id, int provider_id) {
if (!context_)
return;
ServiceWorkerProviderHost* provider_host =
context_->GetProviderHost(render_process_id_, provider_id);
if (!provider_host)
return;
provider_host->AddScriptClient(thread_id);
}
void ServiceWorkerDispatcherHost::OnRemoveScriptClient(
int thread_id, int provider_id) {
if (!context_)
return;
ServiceWorkerProviderHost* provider_host =
context_->GetProviderHost(render_process_id_, provider_id);
if (!provider_host)
return;
provider_host->RemoveScriptClient(thread_id);
}
void ServiceWorkerDispatcherHost::RegistrationComplete(
int32 thread_id,
int32 request_id,
......
......@@ -46,6 +46,8 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
const GURL& pattern);
void OnProviderCreated(int provider_id);
void OnProviderDestroyed(int provider_id);
void OnAddScriptClient(int thread_id, int provider_id);
void OnRemoveScriptClient(int thread_id, int provider_id);
void OnWorkerStarted(int thread_id,
int embedded_worker_id);
void OnWorkerStopped(int embedded_worker_id);
......
......@@ -4,6 +4,7 @@
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "base/stl_util.h"
#include "content/browser/service_worker/service_worker_utils.h"
#include "content/browser/service_worker/service_worker_version.h"
......@@ -17,6 +18,16 @@ ServiceWorkerProviderHost::ServiceWorkerProviderHost(
ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
}
void ServiceWorkerProviderHost::AddScriptClient(int thread_id) {
DCHECK(!ContainsKey(script_client_thread_ids_, thread_id));
script_client_thread_ids_.insert(thread_id);
}
void ServiceWorkerProviderHost::RemoveScriptClient(int thread_id) {
DCHECK(ContainsKey(script_client_thread_ids_, thread_id));
script_client_thread_ids_.erase(thread_id);
}
bool ServiceWorkerProviderHost::ShouldHandleRequest(
ResourceType::Type resource_type) const {
if (ServiceWorkerUtils::IsMainResourceType(resource_type))
......
......@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_
#include <set>
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "webkit/common/resource_type.h"
......@@ -28,12 +30,22 @@ class ServiceWorkerProviderHost
int process_id() const { return process_id_; }
int provider_id() const { return provider_id_; }
// Adds and removes script client thread ID, who is listening events
// dispatched from ServiceWorker to the document (and any of its dedicated
// workers) corresponding to this provider.
void AddScriptClient(int thread_id);
void RemoveScriptClient(int thread_id);
// The service worker version that corresponds with navigator.serviceWorker
// for our document.
ServiceWorkerVersion* associated_version() const {
return associated_version_.get();
}
const std::set<int>& script_client_thread_ids() const {
return script_client_thread_ids_;
}
// Returns true if this provider host should handle requests for
// |resource_type|.
bool ShouldHandleRequest(ResourceType::Type resource_type) const;
......@@ -41,6 +53,7 @@ class ServiceWorkerProviderHost
private:
const int process_id_;
const int provider_id_;
std::set<int> script_client_thread_ids_;
scoped_refptr<ServiceWorkerVersion> associated_version_;
};
......
......@@ -77,6 +77,25 @@ void ServiceWorkerDispatcher::UnregisterServiceWorker(
CurrentWorkerId(), request_id, pattern));
}
void ServiceWorkerDispatcher::AddScriptClient(
int provider_id,
blink::WebServiceWorkerProviderClient* client) {
DCHECK(client);
DCHECK(!ContainsKey(script_clients_, provider_id));
script_clients_[provider_id] = client;
thread_safe_sender_->Send(new ServiceWorkerHostMsg_AddScriptClient(
CurrentWorkerId(), provider_id));
}
void ServiceWorkerDispatcher::RemoveScriptClient(int provider_id) {
// This could be possibly called multiple times to ensure termination.
if (ContainsKey(script_clients_, provider_id)) {
script_clients_.erase(provider_id);
thread_safe_sender_->Send(new ServiceWorkerHostMsg_RemoveScriptClient(
CurrentWorkerId(), provider_id));
}
}
ServiceWorkerDispatcher* ServiceWorkerDispatcher::ThreadSpecificInstance(
ThreadSafeSender* thread_safe_sender) {
if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) {
......
......@@ -5,6 +5,8 @@
#ifndef CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
#define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
#include <map>
#include "base/id_map.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
......@@ -38,22 +40,30 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer {
void OnMessageReceived(const IPC::Message& msg);
bool Send(IPC::Message* msg);
// Corresponds to navigator.registerServiceWorker()
// Corresponds to navigator.serviceWorker.register()
void RegisterServiceWorker(
const GURL& pattern,
const GURL& script_url,
blink::WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks);
// Corresponds to navigator.unregisterServiceWorker()
// Corresponds to navigator.serviceWorker.unregister()
void UnregisterServiceWorker(
const GURL& pattern,
blink::WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks);
// Called when navigator.serviceWorker is instantiated or detached
// for a document whose provider can be identified by |provider_id|.
void AddScriptClient(int provider_id,
blink::WebServiceWorkerProviderClient* client);
void RemoveScriptClient(int provider_id);
// |thread_safe_sender| needs to be passed in because if the call leads to
// construction it will be needed.
static ServiceWorkerDispatcher* ThreadSpecificInstance(
ThreadSafeSender* thread_safe_sender);
private:
typedef std::map<int, blink::WebServiceWorkerProviderClient*> ScriptClientMap;
// WorkerTaskRunner::Observer implementation.
virtual void OnWorkerRunLoopStopped() OVERRIDE;
......@@ -69,6 +79,7 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer {
IDMap<blink::WebServiceWorkerProvider::WebServiceWorkerCallbacks,
IDMapOwnPointer> pending_callbacks_;
ScriptClientMap script_clients_;
scoped_refptr<ThreadSafeSender> thread_safe_sender_;
......
......@@ -9,8 +9,6 @@
#include "content/child/child_thread.h"
#include "content/child/service_worker/service_worker_dispatcher.h"
#include "content/child/thread_safe_sender.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerProviderClient.h"
#include "third_party/WebKit/public/platform/WebURL.h"
using blink::WebURL;
......@@ -18,34 +16,40 @@ using blink::WebURL;
namespace content {
WebServiceWorkerProviderImpl::WebServiceWorkerProviderImpl(
ThreadSafeSender* thread_safe_sender)
ThreadSafeSender* thread_safe_sender,
int provider_id)
: thread_safe_sender_(thread_safe_sender),
client_(NULL) {
provider_id_(provider_id) {
}
WebServiceWorkerProviderImpl::~WebServiceWorkerProviderImpl() {
// Make sure the script client is removed.
GetDispatcher()->RemoveScriptClient(provider_id_);
}
void WebServiceWorkerProviderImpl::setClient(
blink::WebServiceWorkerProviderClient* client) {
// TODO(kinuko): We should register the client with provider_id
// so that the client can start listening events for the provider.
client_ = client;
if (client)
GetDispatcher()->AddScriptClient(provider_id_, client);
else
GetDispatcher()->RemoveScriptClient(provider_id_);
}
void WebServiceWorkerProviderImpl::registerServiceWorker(
const WebURL& pattern,
const WebURL& script_url,
WebServiceWorkerCallbacks* callbacks) {
ServiceWorkerDispatcher::ThreadSpecificInstance(thread_safe_sender_)
->RegisterServiceWorker(pattern, script_url, callbacks);
GetDispatcher()->RegisterServiceWorker(pattern, script_url, callbacks);
}
void WebServiceWorkerProviderImpl::unregisterServiceWorker(
const WebURL& pattern,
WebServiceWorkerCallbacks* callbacks) {
ServiceWorkerDispatcher::ThreadSpecificInstance(thread_safe_sender_)
->UnregisterServiceWorker(pattern, callbacks);
GetDispatcher()->UnregisterServiceWorker(pattern, callbacks);
}
ServiceWorkerDispatcher* WebServiceWorkerProviderImpl::GetDispatcher() {
return ServiceWorkerDispatcher::ThreadSpecificInstance(thread_safe_sender_);
}
} // namespace content
......@@ -17,14 +17,14 @@ class WebServiceWorkerProviderClient;
namespace content {
class ServiceWorkerDispatcher;
class ThreadSafeSender;
class WebServiceWorkerProviderImpl
: NON_EXPORTED_BASE(public blink::WebServiceWorkerProvider) {
public:
// TODO(kinuko): This should be given the provider_id from the network
// layer.
explicit WebServiceWorkerProviderImpl(ThreadSafeSender* thread_safe_sender);
WebServiceWorkerProviderImpl(ThreadSafeSender* thread_safe_sender,
int provider_id);
virtual ~WebServiceWorkerProviderImpl();
virtual void setClient(blink::WebServiceWorkerProviderClient* client);
......@@ -37,8 +37,10 @@ class WebServiceWorkerProviderImpl
WebServiceWorkerCallbacks*);
private:
ServiceWorkerDispatcher* GetDispatcher();
scoped_refptr<ThreadSafeSender> thread_safe_sender_;
blink::WebServiceWorkerProviderClient* client_;
const int provider_id_;
DISALLOW_COPY_AND_ASSIGN(WebServiceWorkerProviderImpl);
};
......
......@@ -84,6 +84,16 @@ IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_ProviderCreated,
IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_ProviderDestroyed,
int /* provider_id */)
// Informs the browser of a new scriptable API client in the child process.
IPC_MESSAGE_CONTROL2(ServiceWorkerHostMsg_AddScriptClient,
int /* thread_id */,
int /* provider_id */)
// Informs the browser that the scriptable API client is unregistered.
IPC_MESSAGE_CONTROL2(ServiceWorkerHostMsg_RemoveScriptClient,
int /* thread_id */,
int /* provider_id */)
// Informs the browser that install event handling has finished.
// Sent via EmbeddedWorker. If there was an exception during the
// event handling it'll be reported back separately (to be propagated
......
......@@ -1039,10 +1039,16 @@ blink::WebCookieJar* RenderFrameImpl::cookieJar(blink::WebFrame* frame) {
blink::WebServiceWorkerProvider* RenderFrameImpl::createServiceWorkerProvider(
blink::WebFrame* frame) {
DCHECK(!frame_ || frame_ == frame);
// TODO(kinuko): Get the provider_id for the frame (via dataSource) and
// pass it to the WebServiceWorkerProviderImpl constructor.
// At this point we should have non-null data source.
DCHECK(frame->dataSource());
ServiceWorkerNetworkProvider* provider =
ServiceWorkerNetworkProvider::FromDocumentState(
DocumentState::FromDataSource(frame->dataSource()));
int provider_id = provider ?
provider->provider_id() :
kInvalidServiceWorkerProviderId;
return new WebServiceWorkerProviderImpl(
ChildThread::current()->thread_safe_sender());
ChildThread::current()->thread_safe_sender(), provider_id);
}
void RenderFrameImpl::didAccessInitialDocument(blink::WebFrame* frame) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment