1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
6#define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
7
8#include <map>
9#include <vector>
10
11#include "base/id_map.h"
12#include "base/memory/ref_counted.h"
13#include "base/strings/string16.h"
14#include "content/child/worker_task_runner.h"
15#include "third_party/WebKit/public/platform/WebServiceWorkerError.h"
16#include "third_party/WebKit/public/platform/WebServiceWorkerProvider.h"
17#include "third_party/WebKit/public/platform/WebServiceWorkerState.h"
18
19class GURL;
20
21namespace blink {
22class WebURL;
23}
24
25namespace IPC {
26class Message;
27}
28
29namespace content {
30
31class ServiceWorkerMessageFilter;
32class ServiceWorkerProviderContext;
33class ThreadSafeSender;
34class WebServiceWorkerImpl;
35class WebServiceWorkerRegistrationImpl;
36struct ServiceWorkerObjectInfo;
37struct ServiceWorkerRegistrationObjectInfo;
38struct ServiceWorkerVersionAttributes;
39
40// This class manages communication with the browser process about
41// registration of the service worker, exposed to renderer and worker
42// scripts through methods like navigator.registerServiceWorker().
43class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer {
44 public:
45  typedef blink::WebServiceWorkerProvider::WebServiceWorkerRegistrationCallbacks
46      WebServiceWorkerRegistrationCallbacks;
47  typedef
48      blink::WebServiceWorkerProvider::WebServiceWorkerUnregistrationCallbacks
49      WebServiceWorkerUnregistrationCallbacks;
50  typedef
51      blink::WebServiceWorkerProvider::WebServiceWorkerGetRegistrationCallbacks
52      WebServiceWorkerGetRegistrationCallbacks;
53
54  explicit ServiceWorkerDispatcher(ThreadSafeSender* thread_safe_sender);
55  virtual ~ServiceWorkerDispatcher();
56
57  void OnMessageReceived(const IPC::Message& msg);
58  bool Send(IPC::Message* msg);
59
60  // Corresponds to navigator.serviceWorker.register()
61  void RegisterServiceWorker(
62      int provider_id,
63      const GURL& pattern,
64      const GURL& script_url,
65      WebServiceWorkerRegistrationCallbacks* callbacks);
66  // Corresponds to navigator.serviceWorker.unregister()
67  void UnregisterServiceWorker(
68      int provider_id,
69      const GURL& pattern,
70      WebServiceWorkerUnregistrationCallbacks* callbacks);
71  // Corresponds to navigator.serviceWorker.getRegistration()
72  void GetRegistration(
73      int provider_id,
74      const GURL& document_url,
75      WebServiceWorkerRegistrationCallbacks* callbacks);
76
77  // Called when a new provider context for a document is created. Usually
78  // this happens when a new document is being loaded, and is called much
79  // earlier than AddScriptClient.
80  // (This is attached only to the document thread's ServiceWorkerDispatcher)
81  void AddProviderContext(ServiceWorkerProviderContext* provider_context);
82  void RemoveProviderContext(ServiceWorkerProviderContext* provider_context);
83
84  // Called when navigator.serviceWorker is instantiated or detached
85  // for a document whose provider can be identified by |provider_id|.
86  void AddScriptClient(int provider_id,
87                       blink::WebServiceWorkerProviderClient* client);
88  void RemoveScriptClient(int provider_id);
89
90  // If an existing WebServiceWorkerImpl exists for the Service
91  // Worker, it is returned; otherwise a WebServiceWorkerImpl is
92  // created and its ownership is transferred to the caller. If
93  // |adopt_handle| is true, a ServiceWorkerHandleReference will be
94  // adopted for the specified Service Worker.
95  //
96  // TODO(dominicc): The lifetime of WebServiceWorkerImpl is too tricky; this
97  // method can return an existing WebServiceWorkerImpl, in which case
98  // it is owned by a WebCore::ServiceWorker and the lifetime is not
99  // being transferred to the owner; or it can create a
100  // WebServiceWorkerImpl, in which case ownership is transferred to
101  // the caller who must bounce it to a method that will associate it
102  // with a WebCore::ServiceWorker.
103  WebServiceWorkerImpl* GetServiceWorker(
104      const ServiceWorkerObjectInfo& info,
105      bool adopt_handle);
106
107  // Finds a WebServiceWorkerRegistrationImpl for the specified registration.
108  // If it's not found, returns NULL. If |adopt_handle| is true,
109  // a ServiceWorkerRegistrationHandleReference will be adopted for the
110  // registration.
111  WebServiceWorkerRegistrationImpl* FindServiceWorkerRegistration(
112      const ServiceWorkerRegistrationObjectInfo& info,
113      bool adopt_handle);
114
115  // Creates a WebServiceWorkerRegistrationImpl for the specified registration
116  // and transfers its ownership to the caller. If |adopt_handle| is true, a
117  // ServiceWorkerRegistrationHandleReference will be adopted for the
118  // registration.
119  WebServiceWorkerRegistrationImpl* CreateServiceWorkerRegistration(
120      const ServiceWorkerRegistrationObjectInfo& info,
121      bool adopt_handle);
122
123  // |thread_safe_sender| needs to be passed in because if the call leads to
124  // construction it will be needed.
125  static ServiceWorkerDispatcher* GetOrCreateThreadSpecificInstance(
126      ThreadSafeSender* thread_safe_sender);
127
128  // Unlike GetOrCreateThreadSpecificInstance() this doesn't create a new
129  // instance if thread-local instance doesn't exist.
130  static ServiceWorkerDispatcher* GetThreadSpecificInstance();
131
132 private:
133  typedef IDMap<WebServiceWorkerRegistrationCallbacks,
134      IDMapOwnPointer> RegistrationCallbackMap;
135  typedef IDMap<WebServiceWorkerUnregistrationCallbacks,
136      IDMapOwnPointer> UnregistrationCallbackMap;
137  typedef IDMap<WebServiceWorkerGetRegistrationCallbacks,
138      IDMapOwnPointer> GetRegistrationCallbackMap;
139  typedef std::map<int, blink::WebServiceWorkerProviderClient*> ScriptClientMap;
140  typedef std::map<int, ServiceWorkerProviderContext*> ProviderContextMap;
141  typedef std::map<int, WebServiceWorkerImpl*> WorkerObjectMap;
142  typedef std::map<int, ServiceWorkerProviderContext*> WorkerToProviderMap;
143  typedef std::map<int, WebServiceWorkerRegistrationImpl*>
144      RegistrationObjectMap;
145
146  friend class WebServiceWorkerImpl;
147  friend class WebServiceWorkerRegistrationImpl;
148
149  // WorkerTaskRunner::Observer implementation.
150  virtual void OnWorkerRunLoopStopped() OVERRIDE;
151
152  void OnAssociateRegistration(int thread_id,
153                               int provider_id,
154                               const ServiceWorkerRegistrationObjectInfo& info,
155                               const ServiceWorkerVersionAttributes& attrs);
156  void OnDisassociateRegistration(int thread_id,
157                                  int provider_id);
158  void OnRegistered(int thread_id,
159                    int request_id,
160                    const ServiceWorkerRegistrationObjectInfo& info,
161                    const ServiceWorkerVersionAttributes& attrs);
162  void OnUnregistered(int thread_id,
163                      int request_id,
164                      bool is_success);
165  void OnDidGetRegistration(int thread_id,
166                            int request_id,
167                            const ServiceWorkerRegistrationObjectInfo& info,
168                            const ServiceWorkerVersionAttributes& attrs);
169  void OnRegistrationError(int thread_id,
170                           int request_id,
171                           blink::WebServiceWorkerError::ErrorType error_type,
172                           const base::string16& message);
173  void OnUnregistrationError(int thread_id,
174                             int request_id,
175                             blink::WebServiceWorkerError::ErrorType error_type,
176                             const base::string16& message);
177  void OnGetRegistrationError(
178      int thread_id,
179      int request_id,
180      blink::WebServiceWorkerError::ErrorType error_type,
181      const base::string16& message);
182  void OnServiceWorkerStateChanged(int thread_id,
183                                   int handle_id,
184                                   blink::WebServiceWorkerState state);
185  void OnSetVersionAttributes(int thread_id,
186                              int provider_id,
187                              int registration_handle_id,
188                              int changed_mask,
189                              const ServiceWorkerVersionAttributes& attributes);
190  void OnUpdateFound(int thread_id,
191                     const ServiceWorkerRegistrationObjectInfo& info);
192  void OnSetControllerServiceWorker(int thread_id,
193                                    int provider_id,
194                                    const ServiceWorkerObjectInfo& info);
195  void OnPostMessage(int thread_id,
196                     int provider_id,
197                     const base::string16& message,
198                     const std::vector<int>& sent_message_port_ids,
199                     const std::vector<int>& new_routing_ids);
200
201  void SetInstallingServiceWorker(
202      int provider_id,
203      int registration_handle_id,
204      const ServiceWorkerObjectInfo& info);
205  void SetWaitingServiceWorker(
206      int provider_id,
207      int registration_handle_id,
208      const ServiceWorkerObjectInfo& info);
209  void SetActiveServiceWorker(
210      int provider_id,
211      int registration_handle_id,
212      const ServiceWorkerObjectInfo& info);
213  void SetReadyRegistration(
214      int provider_id,
215      int registration_handle_id);
216
217  // Keeps map from handle_id to ServiceWorker object.
218  void AddServiceWorker(int handle_id, WebServiceWorkerImpl* worker);
219  void RemoveServiceWorker(int handle_id);
220
221  // Keeps map from registration_handle_id to ServiceWorkerRegistration object.
222  void AddServiceWorkerRegistration(
223      int registration_handle_id,
224      WebServiceWorkerRegistrationImpl* registration);
225  void RemoveServiceWorkerRegistration(
226      int registration_handle_id);
227
228  WebServiceWorkerRegistrationImpl* FindOrCreateRegistration(
229      const ServiceWorkerRegistrationObjectInfo& info,
230      const ServiceWorkerVersionAttributes& attrs);
231
232  RegistrationCallbackMap pending_registration_callbacks_;
233  UnregistrationCallbackMap pending_unregistration_callbacks_;
234  GetRegistrationCallbackMap pending_get_registration_callbacks_;
235  ScriptClientMap script_clients_;
236  ProviderContextMap provider_contexts_;
237  WorkerObjectMap service_workers_;
238  RegistrationObjectMap registrations_;
239
240  // A map for ServiceWorkers that are associated to a particular document
241  // (e.g. as .current).
242  WorkerToProviderMap worker_to_provider_;
243
244  scoped_refptr<ThreadSafeSender> thread_safe_sender_;
245
246  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDispatcher);
247};
248
249}  // namespace content
250
251#endif  // CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
252