Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / embedded_worker_instance.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_EMBEDDED_WORKER_INSTANCE_H_
6 #define CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_INSTANCE_H_
7
8 #include <map>
9 #include <vector>
10
11 #include "base/basictypes.h"
12 #include "base/callback_forward.h"
13 #include "base/gtest_prod_util.h"
14 #include "base/logging.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/observer_list.h"
17 #include "base/strings/string16.h"
18 #include "content/common/content_export.h"
19 #include "content/common/service_worker/service_worker_status_code.h"
20
21 class GURL;
22
23 namespace IPC {
24 class Message;
25 }
26
27 namespace content {
28
29 class EmbeddedWorkerRegistry;
30 struct ServiceWorkerFetchRequest;
31
32 // This gives an interface to control one EmbeddedWorker instance, which
33 // may be 'in-waiting' or running in one of the child processes added by
34 // AddProcessReference().
35 class CONTENT_EXPORT EmbeddedWorkerInstance {
36  public:
37   typedef base::Callback<void(ServiceWorkerStatusCode)> StatusCallback;
38   enum Status {
39     STOPPED,
40     STARTING,
41     RUNNING,
42     STOPPING,
43   };
44
45   class Listener {
46    public:
47     virtual ~Listener() {}
48     virtual void OnStarted() = 0;
49     virtual void OnStopped() = 0;
50     virtual void OnReportException(const base::string16& error_message,
51                                    int line_number,
52                                    int column_number,
53                                    const GURL& source_url) {}
54     virtual void OnReportConsoleMessage(int source_identifier,
55                                         int message_level,
56                                         const base::string16& message,
57                                         int line_number,
58                                         const GURL& source_url) {}
59     // These should return false if the message is not handled by this
60     // listener. (TODO(kinuko): consider using IPC::Listener interface)
61     // TODO(kinuko): Deprecate OnReplyReceived.
62     virtual bool OnMessageReceived(const IPC::Message& message) = 0;
63   };
64
65   ~EmbeddedWorkerInstance();
66
67   // Starts the worker. It is invalid to call this when the worker is not in
68   // STOPPED status. |callback| is invoked when the worker's process is created
69   // if necessary and the IPC to evaluate the worker's script is sent.
70   // Observer::OnStarted() is run when the worker is actually started.
71   void Start(int64 service_worker_version_id,
72              const GURL& scope,
73              const GURL& script_url,
74              const std::vector<int>& possible_process_ids,
75              const StatusCallback& callback);
76
77   // Stops the worker. It is invalid to call this when the worker is
78   // not in STARTING or RUNNING status.
79   // This returns false if stopping a worker fails immediately, e.g. when
80   // IPC couldn't be sent to the worker.
81   ServiceWorkerStatusCode Stop();
82
83   // Sends |message| to the embedded worker running in the child process.
84   // It is invalid to call this while the worker is not in RUNNING status.
85   ServiceWorkerStatusCode SendMessage(const IPC::Message& message);
86
87   // Add or remove |process_id| to the internal process set where this
88   // worker can be started.
89   void AddProcessReference(int process_id);
90   void ReleaseProcessReference(int process_id);
91   bool HasProcessToRun() const { return !process_refs_.empty(); }
92
93   int embedded_worker_id() const { return embedded_worker_id_; }
94   Status status() const { return status_; }
95   int process_id() const { return process_id_; }
96   int thread_id() const { return thread_id_; }
97   int worker_devtools_agent_route_id() const {
98     return worker_devtools_agent_route_id_;
99   }
100
101   void AddListener(Listener* listener);
102   void RemoveListener(Listener* listener);
103
104  private:
105   typedef ObserverList<Listener> ListenerList;
106
107   friend class EmbeddedWorkerRegistry;
108   FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerInstanceTest, StartAndStop);
109
110   typedef std::map<int, int> ProcessRefMap;
111
112   // Constructor is called via EmbeddedWorkerRegistry::CreateWorker().
113   // This instance holds a ref of |registry|.
114   EmbeddedWorkerInstance(EmbeddedWorkerRegistry* registry,
115                          int embedded_worker_id);
116
117   // Called back from EmbeddedWorkerRegistry after Start() passes control to the
118   // UI thread to acquire a reference to the process.
119   void RecordProcessId(int process_id,
120                        ServiceWorkerStatusCode status,
121                        int worker_devtools_agent_route_id);
122
123   // Called back from Registry when the worker instance has ack'ed that
124   // it finished loading the script.
125   void OnScriptLoaded();
126
127   // Called back from Registry when the worker instance has ack'ed that
128   // it failed to load the script.
129   void OnScriptLoadFailed();
130
131   // Called back from Registry when the worker instance has ack'ed that
132   // its WorkerGlobalScope is actually started and parsed on |thread_id| in the
133   // child process.
134   // This will change the internal status from STARTING to RUNNING.
135   void OnStarted(int thread_id);
136
137   // Called back from Registry when the worker instance has ack'ed that
138   // its WorkerGlobalScope is actually stopped in the child process.
139   // This will change the internal status from STARTING or RUNNING to
140   // STOPPED.
141   void OnStopped();
142
143   // Called back from Registry when the worker instance sends message
144   // to the browser (i.e. EmbeddedWorker observers).
145   // Returns false if the message is not handled.
146   bool OnMessageReceived(const IPC::Message& message);
147
148   // Called back from Registry when the worker instance reports the exception.
149   void OnReportException(const base::string16& error_message,
150                          int line_number,
151                          int column_number,
152                          const GURL& source_url);
153
154   // Called back from Registry when the worker instance reports to the console.
155   void OnReportConsoleMessage(int source_identifier,
156                               int message_level,
157                               const base::string16& message,
158                               int line_number,
159                               const GURL& source_url);
160
161   // Chooses a list of processes to try to start this worker in, ordered by how
162   // many clients are currently in those processes.
163   std::vector<int> SortProcesses(
164       const std::vector<int>& possible_process_ids) const;
165
166   scoped_refptr<EmbeddedWorkerRegistry> registry_;
167   const int embedded_worker_id_;
168   Status status_;
169
170   // Current running information. -1 indicates the worker is not running.
171   int process_id_;
172   int thread_id_;
173   int worker_devtools_agent_route_id_;
174
175   ProcessRefMap process_refs_;
176   ListenerList listener_list_;
177
178   DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstance);
179 };
180
181 }  // namespace content
182
183 #endif  // CONTENT_BROWSER_SERVICE_WORKER_EMBEDDED_WORKER_INSTANCE_H_