blob: 234b734e0fbc0e9e0528c27e236ba008745e6218 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
#define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
#include <stdint.h>
#include <map>
#include <memory>
#include <set>
#include <vector>
#include "base/id_map.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/child/worker_thread.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProvider.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistration.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerState.h"
class GURL;
namespace base {
class SingleThreadTaskRunner;
}
namespace IPC {
class Message;
}
struct ServiceWorkerMsg_MessageToDocument_Params;
struct ServiceWorkerMsg_SetControllerServiceWorker_Params;
namespace content {
class ServiceWorkerHandleReference;
class ServiceWorkerProviderContext;
class ServiceWorkerRegistrationHandleReference;
class ThreadSafeSender;
class WebServiceWorkerImpl;
class WebServiceWorkerRegistrationImpl;
struct ServiceWorkerObjectInfo;
struct ServiceWorkerRegistrationObjectInfo;
struct ServiceWorkerVersionAttributes;
// This class manages communication with the browser process about
// registration of the service worker, exposed to renderer and worker
// scripts through methods like navigator.registerServiceWorker().
class CONTENT_EXPORT ServiceWorkerDispatcher : public WorkerThread::Observer {
public:
typedef blink::WebServiceWorkerProvider::WebServiceWorkerRegistrationCallbacks
WebServiceWorkerRegistrationCallbacks;
typedef blink::WebServiceWorkerRegistration::WebServiceWorkerUpdateCallbacks
WebServiceWorkerUpdateCallbacks;
typedef blink::WebServiceWorkerRegistration::
WebServiceWorkerUnregistrationCallbacks
WebServiceWorkerUnregistrationCallbacks;
typedef
blink::WebServiceWorkerProvider::WebServiceWorkerGetRegistrationCallbacks
WebServiceWorkerGetRegistrationCallbacks;
typedef
blink::WebServiceWorkerProvider::WebServiceWorkerGetRegistrationsCallbacks
WebServiceWorkerGetRegistrationsCallbacks;
typedef blink::WebServiceWorkerProvider::
WebServiceWorkerGetRegistrationForReadyCallbacks
WebServiceWorkerGetRegistrationForReadyCallbacks;
using WebEnableNavigationPreloadCallbacks =
blink::WebServiceWorkerRegistration::WebEnableNavigationPreloadCallbacks;
using WebGetNavigationPreloadStateCallbacks = blink::
WebServiceWorkerRegistration::WebGetNavigationPreloadStateCallbacks;
using WebSetNavigationPreloadHeaderCallbacks = blink::
WebServiceWorkerRegistration::WebSetNavigationPreloadHeaderCallbacks;
ServiceWorkerDispatcher(
ThreadSafeSender* thread_safe_sender,
base::SingleThreadTaskRunner* main_thread_task_runner);
~ServiceWorkerDispatcher() override;
void OnMessageReceived(const IPC::Message& msg);
// Corresponds to navigator.serviceWorker.register().
void RegisterServiceWorker(
int provider_id,
const GURL& pattern,
const GURL& script_url,
std::unique_ptr<WebServiceWorkerRegistrationCallbacks> callbacks);
// Corresponds to ServiceWorkerRegistration.update().
void UpdateServiceWorker(
int provider_id,
int64_t registration_id,
std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks);
// Corresponds to ServiceWorkerRegistration.unregister().
void UnregisterServiceWorker(
int provider_id,
int64_t registration_id,
std::unique_ptr<WebServiceWorkerUnregistrationCallbacks> callbacks);
// Corresponds to navigator.serviceWorker.getRegistration().
void GetRegistration(
int provider_id,
const GURL& document_url,
std::unique_ptr<WebServiceWorkerGetRegistrationCallbacks> callbacks);
// Corresponds to navigator.serviceWorker.getRegistrations().
void GetRegistrations(
int provider_id,
std::unique_ptr<WebServiceWorkerGetRegistrationsCallbacks> callbacks);
void GetRegistrationForReady(
int provider_id,
std::unique_ptr<WebServiceWorkerGetRegistrationForReadyCallbacks>
callbacks);
// Corresponds to NavigationPreloadManager.enable/disable.
void EnableNavigationPreload(
int provider_id,
int64_t registration_id,
bool enable,
std::unique_ptr<WebEnableNavigationPreloadCallbacks> callbacks);
// Corresponds to NavigationPreloadManager.getState.
void GetNavigationPreloadState(
int provider_id,
int64_t registration_id,
std::unique_ptr<WebGetNavigationPreloadStateCallbacks> callbacks);
// Corresponds to NavigationPreloadManager.setHeaderValue.
void SetNavigationPreloadHeader(
int provider_id,
int64_t registration_id,
const std::string& value,
std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks> callbacks);
// Called when a new provider context for a document is created. Usually
// this happens when a new document is being loaded, and is called much
// earlier than AddScriptClient.
// (This is attached only to the document thread's ServiceWorkerDispatcher)
void AddProviderContext(ServiceWorkerProviderContext* provider_context);
void RemoveProviderContext(ServiceWorkerProviderContext* provider_context);
// Called when navigator.serviceWorker is instantiated or detached
// for a document whose provider can be identified by |provider_id|.
void AddProviderClient(int provider_id,
blink::WebServiceWorkerProviderClient* client);
void RemoveProviderClient(int provider_id);
// Returns the existing service worker or a newly created one with the given
// handle reference. Returns nullptr if the given reference is invalid.
scoped_refptr<WebServiceWorkerImpl> GetOrCreateServiceWorker(
std::unique_ptr<ServiceWorkerHandleReference> handle_ref);
// Returns the existing registration or a newly created one. When a new one is
// created, increments interprocess references to the registration and its
// versions via ServiceWorker(Registration)HandleReference.
scoped_refptr<WebServiceWorkerRegistrationImpl> GetOrCreateRegistration(
const ServiceWorkerRegistrationObjectInfo& info,
const ServiceWorkerVersionAttributes& attrs);
// Returns the existing registration or a newly created one. Always adopts
// interprocess references to the registration and its versions via
// ServiceWorker(Registration)HandleReference.
scoped_refptr<WebServiceWorkerRegistrationImpl> GetOrAdoptRegistration(
const ServiceWorkerRegistrationObjectInfo& info,
const ServiceWorkerVersionAttributes& attrs);
// TODO(falken): Change the caller to just call the appropriate function on
// ServiceWorkerProviderContext directly.
void OnAssociateRegistrationForController(
int provider_id,
const ServiceWorkerRegistrationObjectInfo& info,
const ServiceWorkerVersionAttributes& attrs);
static ServiceWorkerDispatcher* GetOrCreateThreadSpecificInstance(
ThreadSafeSender* thread_safe_sender,
base::SingleThreadTaskRunner* main_thread_task_runner);
// Unlike GetOrCreateThreadSpecificInstance() this doesn't create a new
// instance if thread-local instance doesn't exist.
static ServiceWorkerDispatcher* GetThreadSpecificInstance();
base::SingleThreadTaskRunner* main_thread_task_runner() {
return main_thread_task_runner_.get();
}
private:
using RegistrationCallbackMap =
IDMap<std::unique_ptr<WebServiceWorkerRegistrationCallbacks>>;
using UpdateCallbackMap =
IDMap<std::unique_ptr<WebServiceWorkerUpdateCallbacks>>;
using UnregistrationCallbackMap =
IDMap<std::unique_ptr<WebServiceWorkerUnregistrationCallbacks>>;
using GetRegistrationCallbackMap =
IDMap<std::unique_ptr<WebServiceWorkerGetRegistrationCallbacks>>;
using GetRegistrationsCallbackMap =
IDMap<std::unique_ptr<WebServiceWorkerGetRegistrationsCallbacks>>;
using GetRegistrationForReadyCallbackMap =
IDMap<std::unique_ptr<WebServiceWorkerGetRegistrationForReadyCallbacks>>;
using EnableNavigationPreloadCallbackMap =
IDMap<std::unique_ptr<WebEnableNavigationPreloadCallbacks>>;
using GetNavigationPreloadStateCallbackMap =
IDMap<std::unique_ptr<WebGetNavigationPreloadStateCallbacks>>;
using SetNavigationPreloadHeaderCallbackMap =
IDMap<std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks>>;
using ProviderClientMap =
std::map<int, blink::WebServiceWorkerProviderClient*>;
using ProviderContextMap = std::map<int, ServiceWorkerProviderContext*>;
using WorkerToProviderMap = std::map<int, ServiceWorkerProviderContext*>;
using WorkerObjectMap = std::map<int, WebServiceWorkerImpl*>;
using RegistrationObjectMap =
std::map<int, WebServiceWorkerRegistrationImpl*>;
friend class ServiceWorkerDispatcherTest;
friend class WebServiceWorkerImpl;
friend class WebServiceWorkerRegistrationImpl;
// WorkerThread::Observer implementation.
void WillStopCurrentWorkerThread() override;
void OnRegistered(int thread_id,
int request_id,
const ServiceWorkerRegistrationObjectInfo& info,
const ServiceWorkerVersionAttributes& attrs);
void OnUpdated(int thread_id, int request_id);
void OnUnregistered(int thread_id,
int request_id,
bool is_success);
void OnDidGetRegistration(int thread_id,
int request_id,
const ServiceWorkerRegistrationObjectInfo& info,
const ServiceWorkerVersionAttributes& attrs);
void OnDidGetRegistrations(
int thread_id,
int request_id,
const std::vector<ServiceWorkerRegistrationObjectInfo>& infos,
const std::vector<ServiceWorkerVersionAttributes>& attrs);
void OnDidGetRegistrationForReady(
int thread_id,
int request_id,
const ServiceWorkerRegistrationObjectInfo& info,
const ServiceWorkerVersionAttributes& attrs);
void OnDidEnableNavigationPreload(int thread_id, int request_id);
void OnDidGetNavigationPreloadState(int thread_id,
int request_id,
const NavigationPreloadState& state);
void OnDidSetNavigationPreloadHeader(int thread_id, int request_id);
void OnRegistrationError(int thread_id,
int request_id,
blink::WebServiceWorkerError::ErrorType error_type,
const base::string16& message);
void OnUpdateError(int thread_id,
int request_id,
blink::WebServiceWorkerError::ErrorType error_type,
const base::string16& message);
void OnUnregistrationError(int thread_id,
int request_id,
blink::WebServiceWorkerError::ErrorType error_type,
const base::string16& message);
void OnGetRegistrationError(
int thread_id,
int request_id,
blink::WebServiceWorkerError::ErrorType error_type,
const base::string16& message);
void OnGetRegistrationsError(
int thread_id,
int request_id,
blink::WebServiceWorkerError::ErrorType error_type,
const base::string16& message);
void OnEnableNavigationPreloadError(
int thread_id,
int request_id,
blink::WebServiceWorkerError::ErrorType error_type,
const std::string& message);
void OnGetNavigationPreloadStateError(
int thread_id,
int request_id,
blink::WebServiceWorkerError::ErrorType error_type,
const std::string& message);
void OnSetNavigationPreloadHeaderError(
int thread_id,
int request_id,
blink::WebServiceWorkerError::ErrorType error_type,
const std::string& message);
void OnServiceWorkerStateChanged(int thread_id,
int handle_id,
blink::WebServiceWorkerState state);
void OnSetVersionAttributes(int thread_id,
int registration_handle_id,
int changed_mask,
const ServiceWorkerVersionAttributes& attributes);
void OnUpdateFound(int thread_id,
int registration_handle_id);
void OnSetControllerServiceWorker(
const ServiceWorkerMsg_SetControllerServiceWorker_Params& params);
void OnPostMessage(const ServiceWorkerMsg_MessageToDocument_Params& params);
void OnCountFeature(int thread_id, int provider_id, uint32_t feature);
// Keeps map from handle_id to ServiceWorker object.
void AddServiceWorker(int handle_id, WebServiceWorkerImpl* worker);
void RemoveServiceWorker(int handle_id);
// Keeps map from registration_handle_id to ServiceWorkerRegistration object.
void AddServiceWorkerRegistration(
int registration_handle_id,
WebServiceWorkerRegistrationImpl* registration);
void RemoveServiceWorkerRegistration(
int registration_handle_id);
// Assumes that the given object information retains an interprocess handle
// reference passed from the browser process, and adopts it.
std::unique_ptr<ServiceWorkerRegistrationHandleReference> Adopt(
const ServiceWorkerRegistrationObjectInfo& info);
std::unique_ptr<ServiceWorkerHandleReference> Adopt(
const ServiceWorkerObjectInfo& info);
RegistrationCallbackMap pending_registration_callbacks_;
UpdateCallbackMap pending_update_callbacks_;
UnregistrationCallbackMap pending_unregistration_callbacks_;
GetRegistrationCallbackMap pending_get_registration_callbacks_;
GetRegistrationsCallbackMap pending_get_registrations_callbacks_;
GetRegistrationForReadyCallbackMap get_for_ready_callbacks_;
EnableNavigationPreloadCallbackMap enable_navigation_preload_callbacks_;
GetNavigationPreloadStateCallbackMap get_navigation_preload_state_callbacks_;
SetNavigationPreloadHeaderCallbackMap
set_navigation_preload_header_callbacks_;
ProviderClientMap provider_clients_;
ProviderContextMap provider_contexts_;
WorkerObjectMap service_workers_;
RegistrationObjectMap registrations_;
scoped_refptr<ThreadSafeSender> thread_safe_sender_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDispatcher);
};
} // namespace content
#endif // CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_