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( ...@@ -80,6 +80,10 @@ bool ServiceWorkerDispatcherHost::OnMessageReceived(
OnProviderCreated) OnProviderCreated)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderDestroyed, IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ProviderDestroyed,
OnProviderDestroyed) OnProviderDestroyed)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_AddScriptClient,
OnAddScriptClient)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_RemoveScriptClient,
OnRemoveScriptClient)
IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStarted, IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStarted,
OnWorkerStarted) OnWorkerStarted)
IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStopped, IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerStopped,
...@@ -175,6 +179,28 @@ void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id) { ...@@ -175,6 +179,28 @@ void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id) {
context_->RemoveProviderHost(render_process_id_, 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( void ServiceWorkerDispatcherHost::RegistrationComplete(
int32 thread_id, int32 thread_id,
int32 request_id, int32 request_id,
......
...@@ -46,6 +46,8 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter { ...@@ -46,6 +46,8 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
const GURL& pattern); const GURL& pattern);
void OnProviderCreated(int provider_id); void OnProviderCreated(int provider_id);
void OnProviderDestroyed(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, void OnWorkerStarted(int thread_id,
int embedded_worker_id); int embedded_worker_id);
void OnWorkerStopped(int embedded_worker_id); void OnWorkerStopped(int embedded_worker_id);
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "content/browser/service_worker/service_worker_provider_host.h" #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_utils.h"
#include "content/browser/service_worker/service_worker_version.h" #include "content/browser/service_worker/service_worker_version.h"
...@@ -17,6 +18,16 @@ ServiceWorkerProviderHost::ServiceWorkerProviderHost( ...@@ -17,6 +18,16 @@ ServiceWorkerProviderHost::ServiceWorkerProviderHost(
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( bool ServiceWorkerProviderHost::ShouldHandleRequest(
ResourceType::Type resource_type) const { ResourceType::Type resource_type) const {
if (ServiceWorkerUtils::IsMainResourceType(resource_type)) if (ServiceWorkerUtils::IsMainResourceType(resource_type))
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_ #ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_
#define 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/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "webkit/common/resource_type.h" #include "webkit/common/resource_type.h"
...@@ -28,12 +30,22 @@ class ServiceWorkerProviderHost ...@@ -28,12 +30,22 @@ class ServiceWorkerProviderHost
int process_id() const { return process_id_; } int process_id() const { return process_id_; }
int provider_id() const { return provider_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 // The service worker version that corresponds with navigator.serviceWorker
// for our document. // for our document.
ServiceWorkerVersion* associated_version() const { ServiceWorkerVersion* associated_version() const {
return associated_version_.get(); 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 // Returns true if this provider host should handle requests for
// |resource_type|. // |resource_type|.
bool ShouldHandleRequest(ResourceType::Type resource_type) const; bool ShouldHandleRequest(ResourceType::Type resource_type) const;
...@@ -41,6 +53,7 @@ class ServiceWorkerProviderHost ...@@ -41,6 +53,7 @@ class ServiceWorkerProviderHost
private: private:
const int process_id_; const int process_id_;
const int provider_id_; const int provider_id_;
std::set<int> script_client_thread_ids_;
scoped_refptr<ServiceWorkerVersion> associated_version_; scoped_refptr<ServiceWorkerVersion> associated_version_;
}; };
......
...@@ -77,6 +77,25 @@ void ServiceWorkerDispatcher::UnregisterServiceWorker( ...@@ -77,6 +77,25 @@ void ServiceWorkerDispatcher::UnregisterServiceWorker(
CurrentWorkerId(), request_id, pattern)); 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( ServiceWorkerDispatcher* ServiceWorkerDispatcher::ThreadSpecificInstance(
ThreadSafeSender* thread_safe_sender) { ThreadSafeSender* thread_safe_sender) {
if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) { if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) {
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_ #ifndef CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
#define 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/id_map.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
...@@ -38,22 +40,30 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { ...@@ -38,22 +40,30 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer {
void OnMessageReceived(const IPC::Message& msg); void OnMessageReceived(const IPC::Message& msg);
bool Send(IPC::Message* msg); bool Send(IPC::Message* msg);
// Corresponds to navigator.registerServiceWorker() // Corresponds to navigator.serviceWorker.register()
void RegisterServiceWorker( void RegisterServiceWorker(
const GURL& pattern, const GURL& pattern,
const GURL& script_url, const GURL& script_url,
blink::WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks); blink::WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks);
// Corresponds to navigator.unregisterServiceWorker() // Corresponds to navigator.serviceWorker.unregister()
void UnregisterServiceWorker( void UnregisterServiceWorker(
const GURL& pattern, const GURL& pattern,
blink::WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks); 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 // |thread_safe_sender| needs to be passed in because if the call leads to
// construction it will be needed. // construction it will be needed.
static ServiceWorkerDispatcher* ThreadSpecificInstance( static ServiceWorkerDispatcher* ThreadSpecificInstance(
ThreadSafeSender* thread_safe_sender); ThreadSafeSender* thread_safe_sender);
private: private:
typedef std::map<int, blink::WebServiceWorkerProviderClient*> ScriptClientMap;
// WorkerTaskRunner::Observer implementation. // WorkerTaskRunner::Observer implementation.
virtual void OnWorkerRunLoopStopped() OVERRIDE; virtual void OnWorkerRunLoopStopped() OVERRIDE;
...@@ -69,6 +79,7 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { ...@@ -69,6 +79,7 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer {
IDMap<blink::WebServiceWorkerProvider::WebServiceWorkerCallbacks, IDMap<blink::WebServiceWorkerProvider::WebServiceWorkerCallbacks,
IDMapOwnPointer> pending_callbacks_; IDMapOwnPointer> pending_callbacks_;
ScriptClientMap script_clients_;
scoped_refptr<ThreadSafeSender> thread_safe_sender_; scoped_refptr<ThreadSafeSender> thread_safe_sender_;
......
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
#include "content/child/child_thread.h" #include "content/child/child_thread.h"
#include "content/child/service_worker/service_worker_dispatcher.h" #include "content/child/service_worker/service_worker_dispatcher.h"
#include "content/child/thread_safe_sender.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" #include "third_party/WebKit/public/platform/WebURL.h"
using blink::WebURL; using blink::WebURL;
...@@ -18,34 +16,40 @@ using blink::WebURL; ...@@ -18,34 +16,40 @@ using blink::WebURL;
namespace content { namespace content {
WebServiceWorkerProviderImpl::WebServiceWorkerProviderImpl( WebServiceWorkerProviderImpl::WebServiceWorkerProviderImpl(
ThreadSafeSender* thread_safe_sender) ThreadSafeSender* thread_safe_sender,
int provider_id)
: thread_safe_sender_(thread_safe_sender), : thread_safe_sender_(thread_safe_sender),
client_(NULL) { provider_id_(provider_id) {
} }
WebServiceWorkerProviderImpl::~WebServiceWorkerProviderImpl() { WebServiceWorkerProviderImpl::~WebServiceWorkerProviderImpl() {
// Make sure the script client is removed.
GetDispatcher()->RemoveScriptClient(provider_id_);
} }
void WebServiceWorkerProviderImpl::setClient( void WebServiceWorkerProviderImpl::setClient(
blink::WebServiceWorkerProviderClient* client) { blink::WebServiceWorkerProviderClient* client) {
// TODO(kinuko): We should register the client with provider_id if (client)
// so that the client can start listening events for the provider. GetDispatcher()->AddScriptClient(provider_id_, client);
client_ = client; else
GetDispatcher()->RemoveScriptClient(provider_id_);
} }
void WebServiceWorkerProviderImpl::registerServiceWorker( void WebServiceWorkerProviderImpl::registerServiceWorker(
const WebURL& pattern, const WebURL& pattern,
const WebURL& script_url, const WebURL& script_url,
WebServiceWorkerCallbacks* callbacks) { WebServiceWorkerCallbacks* callbacks) {
ServiceWorkerDispatcher::ThreadSpecificInstance(thread_safe_sender_) GetDispatcher()->RegisterServiceWorker(pattern, script_url, callbacks);
->RegisterServiceWorker(pattern, script_url, callbacks);
} }
void WebServiceWorkerProviderImpl::unregisterServiceWorker( void WebServiceWorkerProviderImpl::unregisterServiceWorker(
const WebURL& pattern, const WebURL& pattern,
WebServiceWorkerCallbacks* callbacks) { WebServiceWorkerCallbacks* callbacks) {
ServiceWorkerDispatcher::ThreadSpecificInstance(thread_safe_sender_) GetDispatcher()->UnregisterServiceWorker(pattern, callbacks);
->UnregisterServiceWorker(pattern, callbacks); }
ServiceWorkerDispatcher* WebServiceWorkerProviderImpl::GetDispatcher() {
return ServiceWorkerDispatcher::ThreadSpecificInstance(thread_safe_sender_);
} }
} // namespace content } // namespace content
...@@ -17,14 +17,14 @@ class WebServiceWorkerProviderClient; ...@@ -17,14 +17,14 @@ class WebServiceWorkerProviderClient;
namespace content { namespace content {
class ServiceWorkerDispatcher;
class ThreadSafeSender; class ThreadSafeSender;
class WebServiceWorkerProviderImpl class WebServiceWorkerProviderImpl
: NON_EXPORTED_BASE(public blink::WebServiceWorkerProvider) { : NON_EXPORTED_BASE(public blink::WebServiceWorkerProvider) {
public: public:
// TODO(kinuko): This should be given the provider_id from the network WebServiceWorkerProviderImpl(ThreadSafeSender* thread_safe_sender,
// layer. int provider_id);
explicit WebServiceWorkerProviderImpl(ThreadSafeSender* thread_safe_sender);
virtual ~WebServiceWorkerProviderImpl(); virtual ~WebServiceWorkerProviderImpl();
virtual void setClient(blink::WebServiceWorkerProviderClient* client); virtual void setClient(blink::WebServiceWorkerProviderClient* client);
...@@ -37,8 +37,10 @@ class WebServiceWorkerProviderImpl ...@@ -37,8 +37,10 @@ class WebServiceWorkerProviderImpl
WebServiceWorkerCallbacks*); WebServiceWorkerCallbacks*);
private: private:
ServiceWorkerDispatcher* GetDispatcher();
scoped_refptr<ThreadSafeSender> thread_safe_sender_; scoped_refptr<ThreadSafeSender> thread_safe_sender_;
blink::WebServiceWorkerProviderClient* client_; const int provider_id_;
DISALLOW_COPY_AND_ASSIGN(WebServiceWorkerProviderImpl); DISALLOW_COPY_AND_ASSIGN(WebServiceWorkerProviderImpl);
}; };
......
...@@ -84,6 +84,16 @@ IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_ProviderCreated, ...@@ -84,6 +84,16 @@ IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_ProviderCreated,
IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_ProviderDestroyed, IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_ProviderDestroyed,
int /* provider_id */) 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. // Informs the browser that install event handling has finished.
// Sent via EmbeddedWorker. If there was an exception during the // Sent via EmbeddedWorker. If there was an exception during the
// event handling it'll be reported back separately (to be propagated // event handling it'll be reported back separately (to be propagated
......
...@@ -1039,10 +1039,16 @@ blink::WebCookieJar* RenderFrameImpl::cookieJar(blink::WebFrame* frame) { ...@@ -1039,10 +1039,16 @@ blink::WebCookieJar* RenderFrameImpl::cookieJar(blink::WebFrame* frame) {
blink::WebServiceWorkerProvider* RenderFrameImpl::createServiceWorkerProvider( blink::WebServiceWorkerProvider* RenderFrameImpl::createServiceWorkerProvider(
blink::WebFrame* frame) { blink::WebFrame* frame) {
DCHECK(!frame_ || frame_ == frame); DCHECK(!frame_ || frame_ == frame);
// TODO(kinuko): Get the provider_id for the frame (via dataSource) and // At this point we should have non-null data source.
// pass it to the WebServiceWorkerProviderImpl constructor. DCHECK(frame->dataSource());
ServiceWorkerNetworkProvider* provider =
ServiceWorkerNetworkProvider::FromDocumentState(
DocumentState::FromDataSource(frame->dataSource()));
int provider_id = provider ?
provider->provider_id() :
kInvalidServiceWorkerProviderId;
return new WebServiceWorkerProviderImpl( return new WebServiceWorkerProviderImpl(
ChildThread::current()->thread_safe_sender()); ChildThread::current()->thread_safe_sender(), provider_id);
} }
void RenderFrameImpl::didAccessInitialDocument(blink::WebFrame* frame) { 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