• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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_WORKER_HOST_WORKER_PROCESS_HOST_H_
6 #define CONTENT_BROWSER_WORKER_HOST_WORKER_PROCESS_HOST_H_
7 
8 #include <list>
9 #include <string>
10 #include <utility>
11 
12 #include "base/basictypes.h"
13 #include "base/files/file_path.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "content/browser/worker_host/worker_document_set.h"
16 #include "content/browser/worker_host/worker_storage_partition.h"
17 #include "content/common/content_export.h"
18 #include "content/public/browser/browser_child_process_host_delegate.h"
19 #include "content/public/browser/browser_child_process_host_iterator.h"
20 #include "content/public/common/process_type.h"
21 #include "ipc/ipc_sender.h"
22 #include "url/gurl.h"
23 #include "webkit/common/resource_type.h"
24 
25 struct ResourceHostMsg_Request;
26 
27 namespace fileapi {
28 class FileSystemContext;
29 }  // namespace fileapi
30 
31 namespace net {
32 class URLRequestContext;
33 }
34 
35 namespace webkit_database {
36 class DatabaseTracker;
37 }  // namespace webkit_database
38 
39 namespace content {
40 class BrowserChildProcessHostImpl;
41 class IndexedDBContextImpl;
42 class ResourceContext;
43 class SocketStreamDispatcherHost;
44 class WorkerServiceImpl;
45 
46 // The WorkerProcessHost is the interface that represents the browser side of
47 // the browser <-> worker communication channel. There will be one
48 // WorkerProcessHost per worker process.  Currently each worker runs in its own
49 // process, but that may change.  However, we do assume (by storing a
50 // net::URLRequestContext) that a WorkerProcessHost serves a single
51 // BrowserContext.
52 class WorkerProcessHost : public BrowserChildProcessHostDelegate,
53                           public IPC::Sender {
54  public:
55   // Contains information about each worker instance, needed to forward messages
56   // between the renderer and worker processes.
57   class WorkerInstance {
58    public:
59     WorkerInstance(const GURL& url,
60                    const base::string16& name,
61                    int worker_route_id,
62                    int parent_process_id,
63                    int64 main_resource_appcache_id,
64                    ResourceContext* resource_context,
65                    const WorkerStoragePartition& partition);
66     // Used for pending instances. Rest of the parameters are ignored.
67     WorkerInstance(const GURL& url,
68                    bool shared,
69                    const base::string16& name,
70                    ResourceContext* resource_context,
71                    const WorkerStoragePartition& partition);
72     ~WorkerInstance();
73 
74     // Unique identifier for a worker client.
75     typedef std::pair<WorkerMessageFilter*, int> FilterInfo;
76 
77     // APIs to manage the filter list for a given instance.
78     void AddFilter(WorkerMessageFilter* filter, int route_id);
79     void RemoveFilter(WorkerMessageFilter* filter, int route_id);
80     void RemoveFilters(WorkerMessageFilter* filter);
81     bool HasFilter(WorkerMessageFilter* filter, int route_id) const;
82     bool RendererIsParent(int render_process_id, int render_view_id) const;
NumFilters()83     int NumFilters() const { return filters_.size(); }
84     // Returns the single filter (must only be one).
85     FilterInfo GetFilter() const;
86 
87     typedef std::list<FilterInfo> FilterList;
filters()88     const FilterList& filters() const { return filters_; }
89 
90     // Checks if this WorkerInstance matches the passed url/name params
91     // (per the comparison algorithm in the WebWorkers spec). This API only
92     // applies to shared workers.
93     bool Matches(
94         const GURL& url,
95         const base::string16& name,
96         const WorkerStoragePartition& partition,
97         ResourceContext* resource_context) const;
98 
99     // Shares the passed instance's WorkerDocumentSet with this instance. This
100     // instance's current WorkerDocumentSet is dereferenced (and freed if this
101     // is the only reference) as a result.
ShareDocumentSet(const WorkerInstance & instance)102     void ShareDocumentSet(const WorkerInstance& instance) {
103       worker_document_set_ = instance.worker_document_set_;
104     };
105 
106     // Accessors
closed()107     bool closed() const { return closed_; }
set_closed(bool closed)108     void set_closed(bool closed) { closed_ = closed; }
url()109     const GURL& url() const { return url_; }
name()110     const base::string16 name() const { return name_; }
worker_route_id()111     int worker_route_id() const { return worker_route_id_; }
parent_process_id()112     int parent_process_id() const { return parent_process_id_; }
main_resource_appcache_id()113     int64 main_resource_appcache_id() const {
114       return main_resource_appcache_id_;
115     }
worker_document_set()116     WorkerDocumentSet* worker_document_set() const {
117       return worker_document_set_.get();
118     }
resource_context()119     ResourceContext* resource_context() const {
120       return resource_context_;
121     }
partition()122     const WorkerStoragePartition& partition() const {
123       return partition_;
124     }
125 
126    private:
127     // Set of all filters (clients) associated with this worker.
128     GURL url_;
129     bool closed_;
130     base::string16 name_;
131     int worker_route_id_;
132     int parent_process_id_;
133     int64 main_resource_appcache_id_;
134     FilterList filters_;
135     scoped_refptr<WorkerDocumentSet> worker_document_set_;
136     ResourceContext* const resource_context_;
137     WorkerStoragePartition partition_;
138   };
139 
140   WorkerProcessHost(ResourceContext* resource_context,
141                     const WorkerStoragePartition& partition);
142   virtual ~WorkerProcessHost();
143 
144   // IPC::Sender implementation:
145   virtual bool Send(IPC::Message* message) OVERRIDE;
146 
147   // Starts the process.  Returns true iff it succeeded.
148   // |render_process_id| is the renderer process responsible for starting this
149   // worker.
150   bool Init(int render_process_id);
151 
152   // Creates a worker object in the process.
153   void CreateWorker(const WorkerInstance& instance);
154 
155   // Returns true iff the given message from a renderer process was forwarded to
156   // the worker.
157   bool FilterMessage(const IPC::Message& message, WorkerMessageFilter* filter);
158 
159   void FilterShutdown(WorkerMessageFilter* filter);
160 
161   // Shuts down any shared workers that are no longer referenced by active
162   // documents.
163   void DocumentDetached(WorkerMessageFilter* filter,
164                         unsigned long long document_id);
165 
166   // Terminates the given worker, i.e. based on a UI action.
167   CONTENT_EXPORT void TerminateWorker(int worker_route_id);
168 
169   // Callers can reduce the WorkerProcess' priority.
170   void SetBackgrounded(bool backgrounded);
171 
172   CONTENT_EXPORT const ChildProcessData& GetData();
173 
174   typedef std::list<WorkerInstance> Instances;
instances()175   const Instances& instances() const { return instances_; }
176 
resource_context()177   ResourceContext* resource_context() const {
178     return resource_context_;
179   }
180 
process_launched()181   bool process_launched() const { return process_launched_; }
182 
183  protected:
184   friend class WorkerServiceImpl;
185 
mutable_instances()186   Instances& mutable_instances() { return instances_; }
187 
188  private:
189   // BrowserChildProcessHostDelegate implementation:
190   virtual void OnProcessLaunched() OVERRIDE;
191   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
192 
193   // Creates and adds the message filters.
194   void CreateMessageFilters(int render_process_id);
195 
196   void OnWorkerContextClosed(int worker_route_id);
197   void OnAllowDatabase(int worker_route_id,
198                        const GURL& url,
199                        const base::string16& name,
200                        const base::string16& display_name,
201                        unsigned long estimated_size,
202                        bool* result);
203   void OnAllowFileSystem(int worker_route_id,
204                          const GURL& url,
205                          bool* result);
206   void OnAllowIndexedDB(int worker_route_id,
207                         const GURL& url,
208                         const base::string16& name,
209                         bool* result);
210   void OnForceKillWorkerProcess();
211 
212   // Relays a message to the given endpoint.  Takes care of parsing the message
213   // if it contains a message port and sending it a valid route id.
214   void RelayMessage(const IPC::Message& message,
215                     WorkerMessageFilter* filter,
216                     int route_id);
217 
218   void ShutdownSocketStreamDispatcherHostIfNecessary();
219 
220   virtual bool CanShutdown() OVERRIDE;
221 
222   // Updates the title shown in the task manager.
223   void UpdateTitle();
224 
225   // Return a vector of all the render process/render view IDs that use the
226   // given worker.
227   std::vector<std::pair<int, int> > GetRenderViewIDsForWorker(int route_id);
228 
229   // Callbacks for ResourceMessageFilter and SocketStreamDispatcherHost.
230   void GetContexts(const ResourceHostMsg_Request& request,
231                    ResourceContext** resource_context,
232                    net::URLRequestContext** request_context);
233   net::URLRequestContext* GetRequestContext(ResourceType::Type resource_type);
234 
235   Instances instances_;
236 
237   ResourceContext* const resource_context_;
238   WorkerStoragePartition partition_;
239 
240   // A reference to the filter associated with this worker process.  We need to
241   // keep this around since we'll use it when forward messages to the worker
242   // process.
243   scoped_refptr<WorkerMessageFilter> worker_message_filter_;
244 
245   scoped_ptr<BrowserChildProcessHostImpl> process_;
246   bool process_launched_;
247 
248   scoped_refptr<SocketStreamDispatcherHost> socket_stream_dispatcher_host_;
249 
250   DISALLOW_COPY_AND_ASSIGN(WorkerProcessHost);
251 };
252 
253 class WorkerProcessHostIterator
254     : public BrowserChildProcessHostTypeIterator<WorkerProcessHost> {
255  public:
WorkerProcessHostIterator()256   WorkerProcessHostIterator()
257       : BrowserChildProcessHostTypeIterator<WorkerProcessHost>(
258             PROCESS_TYPE_WORKER) {
259   }
260 };
261 
262 }  // namespace content
263 
264 #endif  // CONTENT_BROWSER_WORKER_HOST_WORKER_PROCESS_HOST_H_
265