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