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