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