Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_version.h
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_BROWSER_SERVICE_WORKER_SERVICE_WORKER_VERSION_H_
6 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_VERSION_H_
7
8 #include <vector>
9
10 #include "base/basictypes.h"
11 #include "base/callback.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/id_map.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/observer_list.h"
17 #include "content/browser/service_worker/embedded_worker_instance.h"
18 #include "content/common/content_export.h"
19 #include "content/common/service_worker/service_worker_status_code.h"
20 #include "content/common/service_worker/service_worker_types.h"
21 #include "third_party/WebKit/public/platform/WebServiceWorkerEventResult.h"
22
23 class GURL;
24
25 namespace content {
26
27 class EmbeddedWorkerRegistry;
28 class ServiceWorkerContextCore;
29 class ServiceWorkerProviderHost;
30 class ServiceWorkerRegistration;
31 class ServiceWorkerVersionInfo;
32
33 // This class corresponds to a specific version of a ServiceWorker
34 // script for a given pattern. When a script is upgraded, there may be
35 // more than one ServiceWorkerVersion "running" at a time, but only
36 // one of them is active. This class connects the actual script with a
37 // running worker.
38 //
39 // is_shutdown_ detects the live-ness of the object itself. If the object is
40 // shut down, then it is in the process of being deleted from memory.
41 // This happens when a version is replaced as well as at browser shutdown.
42 class CONTENT_EXPORT ServiceWorkerVersion
43     : NON_EXPORTED_BASE(public base::RefCounted<ServiceWorkerVersion>),
44       public EmbeddedWorkerInstance::Listener {
45  public:
46   typedef base::Callback<void(ServiceWorkerStatusCode)> StatusCallback;
47   typedef base::Callback<void(ServiceWorkerStatusCode,
48                               const IPC::Message& message)> MessageCallback;
49   typedef base::Callback<void(ServiceWorkerStatusCode,
50                               ServiceWorkerFetchEventResult,
51                               const ServiceWorkerResponse&)> FetchCallback;
52
53   enum RunningStatus {
54     STOPPED = EmbeddedWorkerInstance::STOPPED,
55     STARTING = EmbeddedWorkerInstance::STARTING,
56     RUNNING = EmbeddedWorkerInstance::RUNNING,
57     STOPPING = EmbeddedWorkerInstance::STOPPING,
58   };
59
60   // Current version status; some of the status (e.g. INSTALLED and ACTIVE)
61   // should be persisted unlike running status.
62   enum Status {
63     NEW,         // The version is just created.
64     INSTALLING,  // Install event is dispatched and being handled.
65     INSTALLED,   // Install event is finished and is ready to be activated.
66     ACTIVATING,  // Activate event is dispatched and being handled.
67     ACTIVE,      // Activation is finished and can run as active.
68     DEACTIVATED, // The version is no longer running as active, due to
69                  // unregistration or replace. (TODO(kinuko): we may need
70                  // different states for different termination sequences)
71   };
72
73   class Listener {
74    public:
75     virtual void OnWorkerStarted(ServiceWorkerVersion* version) = 0;
76     virtual void OnWorkerStopped(ServiceWorkerVersion* version) = 0;
77     virtual void OnVersionStateChanged(ServiceWorkerVersion* version) = 0;
78     virtual void OnErrorReported(ServiceWorkerVersion* version,
79                                  const base::string16& error_message,
80                                  int line_number,
81                                  int column_number,
82                                  const GURL& source_url) = 0;
83     virtual void OnReportConsoleMessage(ServiceWorkerVersion* version,
84                                         int source_identifier,
85                                         int message_level,
86                                         const base::string16& message,
87                                         int line_number,
88                                         const GURL& source_url) = 0;
89   };
90
91   ServiceWorkerVersion(
92       ServiceWorkerRegistration* registration,
93       int64 version_id,
94       base::WeakPtr<ServiceWorkerContextCore> context);
95
96   int64 version_id() const { return version_id_; }
97   int64 registration_id() const { return registration_id_; }
98
99   RunningStatus running_status() const {
100     return static_cast<RunningStatus>(embedded_worker_->status());
101   }
102
103   ServiceWorkerVersionInfo GetInfo();
104
105   Status status() const { return status_; }
106
107   // This sets the new status and also run status change callbacks
108   // if there're any (see RegisterStatusChangeCallback).
109   void SetStatus(Status status);
110
111   // Registers status change callback. (This is for one-off observation,
112   // the consumer needs to re-register if it wants to continue observing
113   // status changes)
114   void RegisterStatusChangeCallback(const base::Closure& callback);
115
116   // Starts an embedded worker for this version.
117   // This returns OK (success) if the worker is already running.
118   void StartWorker(const StatusCallback& callback);
119
120   // Starts an embedded worker for this version.
121   // |potential_process_ids| is a list of processes in which to start the
122   // worker.
123   // This returns OK (success) if the worker is already running.
124   void StartWorkerWithCandidateProcesses(
125       const std::vector<int>& potential_process_ids,
126       const StatusCallback& callback);
127
128   // Starts an embedded worker for this version.
129   // This returns OK (success) if the worker is already stopped.
130   void StopWorker(const StatusCallback& callback);
131
132   // Sends an IPC message to the worker.
133   // If the worker is not running this first tries to start it by
134   // calling StartWorker internally.
135   // |callback| can be null if the sender does not need to know if the
136   // message is successfully sent or not.
137   void SendMessage(const IPC::Message& message, const StatusCallback& callback);
138
139   // Sends install event to the associated embedded worker and asynchronously
140   // calls |callback| when it errors out or it gets response from the worker
141   // to notify install completion.
142   // |active_version_id| must be a valid positive ID
143   // if there's an active (previous) version running.
144   //
145   // This must be called when the status() is NEW. Calling this changes
146   // the version's status to INSTALLING.
147   // Upon completion, the version's status will be changed to INSTALLED
148   // on success, or back to NEW on failure.
149   void DispatchInstallEvent(int active_version_id,
150                             const StatusCallback& callback);
151
152   // Sends activate event to the associated embedded worker and asynchronously
153   // calls |callback| when it errors out or it gets response from the worker
154   // to notify activation completion.
155   //
156   // This must be called when the status() is INSTALLED. Calling this changes
157   // the version's status to ACTIVATING.
158   // Upon completion, the version's status will be changed to ACTIVE
159   // on success, or back to INSTALLED on failure.
160   void DispatchActivateEvent(const StatusCallback& callback);
161
162   // Sends fetch event to the associated embedded worker and calls
163   // |callback| with the response from the worker.
164   //
165   // This must be called when the status() is ACTIVE. Calling this in other
166   // statuses will result in an error SERVICE_WORKER_ERROR_FAILED.
167   void DispatchFetchEvent(const ServiceWorkerFetchRequest& request,
168                           const FetchCallback& callback);
169
170   // Sends sync event to the associated embedded worker and asynchronously calls
171   // |callback| when it errors out or it gets response from the worker to notify
172   // completion.
173   //
174   // This must be called when the status() is ACTIVE.
175   void DispatchSyncEvent(const StatusCallback& callback);
176
177   // These are expected to be called when a renderer process host for the
178   // same-origin as for this ServiceWorkerVersion is created.  The added
179   // processes are used to run an in-renderer embedded worker.
180   void AddProcessToWorker(int process_id);
181   void RemoveProcessFromWorker(int process_id);
182
183   // Returns true if this has at least one process to run.
184   bool HasProcessToRun() const;
185
186   // Adds and removes |provider_host| as a controllee of this ServiceWorker.
187   void AddControllee(ServiceWorkerProviderHost* provider_host);
188   void RemoveControllee(ServiceWorkerProviderHost* provider_host);
189   void AddPendingControllee(ServiceWorkerProviderHost* provider_host);
190   void RemovePendingControllee(ServiceWorkerProviderHost* provider_host);
191
192   // Returns if it has (non-pending) controllee.
193   bool HasControllee() const { return !controllee_map_.empty(); }
194
195   // Adds and removes Listeners.
196   void AddListener(Listener* listener);
197   void RemoveListener(Listener* listener);
198
199   EmbeddedWorkerInstance* embedded_worker() { return embedded_worker_.get(); }
200
201   // EmbeddedWorkerInstance::Listener overrides:
202   virtual void OnStarted() OVERRIDE;
203   virtual void OnStopped() OVERRIDE;
204   virtual void OnReportException(const base::string16& error_message,
205                                  int line_number,
206                                  int column_number,
207                                  const GURL& source_url) OVERRIDE;
208   virtual void OnReportConsoleMessage(int source_identifier,
209                                       int message_level,
210                                       const base::string16& message,
211                                       int line_number,
212                                       const GURL& source_url) OVERRIDE;
213   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
214
215   void AddToScriptCache(const GURL& url, int64 resource_id);
216   int64 LookupInScriptCache(const GURL& url);
217
218  private:
219   typedef ServiceWorkerVersion self;
220   typedef std::map<ServiceWorkerProviderHost*, int> ControlleeMap;
221   typedef IDMap<ServiceWorkerProviderHost> ControlleeByIDMap;
222   typedef std::map<GURL, int64> ResourceIDMap;
223   friend class base::RefCounted<ServiceWorkerVersion>;
224
225   virtual ~ServiceWorkerVersion();
226
227   void RunStartWorkerCallbacksOnError(ServiceWorkerStatusCode status);
228
229   void DispatchInstallEventAfterStartWorker(int active_version_id,
230                                             const StatusCallback& callback);
231   void DispatchActivateEventAfterStartWorker(const StatusCallback& callback);
232
233   // Message handlers.
234   void OnGetClientDocuments(int request_id);
235   void OnActivateEventFinished(int request_id,
236                                blink::WebServiceWorkerEventResult result);
237   void OnInstallEventFinished(int request_id,
238                               blink::WebServiceWorkerEventResult result);
239   void OnFetchEventFinished(int request_id,
240                             ServiceWorkerFetchEventResult result,
241                             const ServiceWorkerResponse& response);
242   void OnSyncEventFinished(int request_id);
243   void OnPostMessageToDocument(int client_id,
244                                const base::string16& message,
245                                const std::vector<int>& sent_message_port_ids);
246
247   const int64 version_id_;
248   int64 registration_id_;
249   GURL script_url_;
250   GURL scope_;
251   Status status_;
252   scoped_ptr<EmbeddedWorkerInstance> embedded_worker_;
253   std::vector<StatusCallback> start_callbacks_;
254   std::vector<StatusCallback> stop_callbacks_;
255   std::vector<base::Closure> status_change_callbacks_;
256
257   // Message callbacks.
258   IDMap<StatusCallback, IDMapOwnPointer> activate_callbacks_;
259   IDMap<StatusCallback, IDMapOwnPointer> install_callbacks_;
260   IDMap<FetchCallback, IDMapOwnPointer> fetch_callbacks_;
261   IDMap<StatusCallback, IDMapOwnPointer> sync_callbacks_;
262
263   ControlleeMap controllee_map_;
264   ControlleeByIDMap controllee_by_id_;
265   base::WeakPtr<ServiceWorkerContextCore> context_;
266   ObserverList<Listener> listeners_;
267
268   ResourceIDMap script_cache_map_;
269
270   base::WeakPtrFactory<ServiceWorkerVersion> weak_factory_;
271
272   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersion);
273 };
274
275 }  // namespace content
276
277 #endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_VERSION_H_