OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/worker_host/worker_process_host.h" | 5 #include "chrome/browser/worker_host/worker_process_host.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
15 #include "chrome/browser/appcache/appcache_dispatcher_host.h" | 15 #include "chrome/browser/appcache/appcache_dispatcher_host.h" |
16 #include "chrome/browser/browser_thread.h" | 16 #include "chrome/browser/browser_thread.h" |
17 #include "chrome/browser/child_process_security_policy.h" | 17 #include "chrome/browser/child_process_security_policy.h" |
18 #include "chrome/browser/content_settings/host_content_settings_map.h" | 18 #include "chrome/browser/content_settings/host_content_settings_map.h" |
19 #include "chrome/browser/file_system/file_system_dispatcher_host.h" | 19 #include "chrome/browser/file_system/file_system_dispatcher_host.h" |
20 #include "chrome/browser/mime_registry_message_filter.h" | 20 #include "chrome/browser/mime_registry_message_filter.h" |
21 #include "chrome/browser/net/chrome_url_request_context.h" | 21 #include "chrome/browser/net/chrome_url_request_context.h" |
22 #include "chrome/browser/profiles/profile.h" | |
23 #include "chrome/browser/renderer_host/blob_message_filter.h" | 22 #include "chrome/browser/renderer_host/blob_message_filter.h" |
24 #include "chrome/browser/renderer_host/database_message_filter.h" | 23 #include "chrome/browser/renderer_host/database_message_filter.h" |
25 #include "chrome/browser/renderer_host/file_utilities_message_filter.h" | 24 #include "chrome/browser/renderer_host/file_utilities_message_filter.h" |
26 #include "chrome/browser/renderer_host/render_message_filter.h" | |
27 #include "chrome/browser/renderer_host/render_view_host.h" | 25 #include "chrome/browser/renderer_host/render_view_host.h" |
28 #include "chrome/browser/renderer_host/render_view_host_delegate.h" | 26 #include "chrome/browser/renderer_host/render_view_host_delegate.h" |
29 #include "chrome/browser/renderer_host/render_view_host_notification_task.h" | 27 #include "chrome/browser/renderer_host/render_view_host_notification_task.h" |
30 #include "chrome/browser/renderer_host/socket_stream_dispatcher_host.h" | 28 #include "chrome/browser/renderer_host/socket_stream_dispatcher_host.h" |
31 #include "chrome/browser/worker_host/message_port_dispatcher.h" | 29 #include "chrome/browser/worker_host/message_port_service.h" |
| 30 #include "chrome/browser/worker_host/worker_message_filter.h" |
32 #include "chrome/browser/worker_host/worker_service.h" | 31 #include "chrome/browser/worker_host/worker_service.h" |
33 #include "chrome/common/chrome_switches.h" | 32 #include "chrome/common/chrome_switches.h" |
34 #include "chrome/common/debug_flags.h" | 33 #include "chrome/common/debug_flags.h" |
35 #include "chrome/common/notification_service.h" | |
36 #include "chrome/common/render_messages.h" | 34 #include "chrome/common/render_messages.h" |
37 #include "chrome/common/render_messages_params.h" | 35 #include "chrome/common/render_messages_params.h" |
38 #include "chrome/common/result_codes.h" | 36 #include "chrome/common/result_codes.h" |
39 #include "chrome/common/worker_messages.h" | 37 #include "chrome/common/worker_messages.h" |
40 #include "net/base/mime_util.h" | 38 #include "net/base/mime_util.h" |
41 #include "ipc/ipc_switches.h" | 39 #include "ipc/ipc_switches.h" |
42 #include "net/base/registry_controlled_domain.h" | 40 #include "net/base/registry_controlled_domain.h" |
43 #include "webkit/fileapi/file_system_path_manager.h" | 41 #include "webkit/fileapi/file_system_path_manager.h" |
44 | 42 |
45 namespace { | 43 namespace { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 } | 82 } |
85 } | 83 } |
86 | 84 |
87 private: | 85 private: |
88 int render_process_unique_id_; | 86 int render_process_unique_id_; |
89 int render_view_id_; | 87 int render_view_id_; |
90 }; | 88 }; |
91 | 89 |
92 WorkerProcessHost::WorkerProcessHost( | 90 WorkerProcessHost::WorkerProcessHost( |
93 ResourceDispatcherHost* resource_dispatcher_host, | 91 ResourceDispatcherHost* resource_dispatcher_host, |
94 ChromeURLRequestContext *request_context) | 92 URLRequestContextGetter* request_context) |
95 : BrowserChildProcessHost(WORKER_PROCESS, resource_dispatcher_host), | 93 : BrowserChildProcessHost(WORKER_PROCESS, resource_dispatcher_host), |
96 request_context_(request_context) { | 94 request_context_(request_context) { |
97 next_route_id_callback_.reset(NewCallbackWithReturnValue( | |
98 WorkerService::GetInstance(), &WorkerService::next_worker_route_id)); | |
99 } | 95 } |
100 | 96 |
101 WorkerProcessHost::~WorkerProcessHost() { | 97 WorkerProcessHost::~WorkerProcessHost() { |
102 // Let interested observers know we are being deleted. | |
103 NotificationService::current()->Notify( | |
104 NotificationType::WORKER_PROCESS_HOST_SHUTDOWN, | |
105 Source<WorkerProcessHost>(this), | |
106 NotificationService::NoDetails()); | |
107 | |
108 // If we crashed, tell the RenderViewHosts. | 98 // If we crashed, tell the RenderViewHosts. |
109 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { | 99 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { |
110 const WorkerDocumentSet::DocumentInfoSet& parents = | 100 const WorkerDocumentSet::DocumentInfoSet& parents = |
111 i->worker_document_set()->documents(); | 101 i->worker_document_set()->documents(); |
112 for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter = | 102 for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter = |
113 parents.begin(); parent_iter != parents.end(); ++parent_iter) { | 103 parents.begin(); parent_iter != parents.end(); ++parent_iter) { |
114 BrowserThread::PostTask( | 104 BrowserThread::PostTask( |
115 BrowserThread::UI, FROM_HERE, | 105 BrowserThread::UI, FROM_HERE, |
116 new WorkerCrashTask(parent_iter->renderer_id(), | 106 new WorkerCrashTask(parent_iter->render_process_id(), |
117 parent_iter->render_view_route_id())); | 107 parent_iter->render_view_id())); |
118 } | 108 } |
119 } | 109 } |
120 | 110 |
121 ChildProcessSecurityPolicy::GetInstance()->Remove(id()); | 111 ChildProcessSecurityPolicy::GetInstance()->Remove(id()); |
122 } | 112 } |
123 | 113 |
124 bool WorkerProcessHost::Init() { | 114 bool WorkerProcessHost::Init(int render_process_id) { |
125 if (!CreateChannel()) | 115 if (!CreateChannel()) |
126 return false; | 116 return false; |
127 | 117 |
128 FilePath exe_path = GetChildPath(true); | 118 FilePath exe_path = GetChildPath(true); |
129 if (exe_path.empty()) | 119 if (exe_path.empty()) |
130 return false; | 120 return false; |
131 | 121 |
132 CommandLine* cmd_line = new CommandLine(exe_path); | 122 CommandLine* cmd_line = new CommandLine(exe_path); |
133 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kWorkerProcess); | 123 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kWorkerProcess); |
134 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id()); | 124 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id()); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 | 178 |
189 ChildProcessSecurityPolicy::GetInstance()->Add(id()); | 179 ChildProcessSecurityPolicy::GetInstance()->Add(id()); |
190 if (!CommandLine::ForCurrentProcess()->HasSwitch( | 180 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
191 switches::kDisableFileSystem)) { | 181 switches::kDisableFileSystem)) { |
192 // Grant most file permissions to this worker. | 182 // Grant most file permissions to this worker. |
193 // PLATFORM_FILE_TEMPORARY, PLATFORM_FILE_HIDDEN and | 183 // PLATFORM_FILE_TEMPORARY, PLATFORM_FILE_HIDDEN and |
194 // PLATFORM_FILE_DELETE_ON_CLOSE are not granted, because no existing API | 184 // PLATFORM_FILE_DELETE_ON_CLOSE are not granted, because no existing API |
195 // requests them. | 185 // requests them. |
196 ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile( | 186 ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile( |
197 id(), | 187 id(), |
198 request_context_->file_system_context()-> | 188 GetChromeURLRequestContext()->file_system_context()-> |
199 path_manager()->base_path(), | 189 path_manager()->base_path(), |
200 base::PLATFORM_FILE_OPEN | | 190 base::PLATFORM_FILE_OPEN | |
201 base::PLATFORM_FILE_CREATE | | 191 base::PLATFORM_FILE_CREATE | |
202 base::PLATFORM_FILE_OPEN_ALWAYS | | 192 base::PLATFORM_FILE_OPEN_ALWAYS | |
203 base::PLATFORM_FILE_CREATE_ALWAYS | | 193 base::PLATFORM_FILE_CREATE_ALWAYS | |
204 base::PLATFORM_FILE_READ | | 194 base::PLATFORM_FILE_READ | |
205 base::PLATFORM_FILE_WRITE | | 195 base::PLATFORM_FILE_WRITE | |
206 base::PLATFORM_FILE_EXCLUSIVE_READ | | 196 base::PLATFORM_FILE_EXCLUSIVE_READ | |
207 base::PLATFORM_FILE_EXCLUSIVE_WRITE | | 197 base::PLATFORM_FILE_EXCLUSIVE_WRITE | |
208 base::PLATFORM_FILE_ASYNC | | 198 base::PLATFORM_FILE_ASYNC | |
209 base::PLATFORM_FILE_TRUNCATE | | 199 base::PLATFORM_FILE_TRUNCATE | |
210 base::PLATFORM_FILE_WRITE_ATTRIBUTES); | 200 base::PLATFORM_FILE_WRITE_ATTRIBUTES); |
211 } | 201 } |
212 | 202 |
213 CreateMessageFilters(); | 203 CreateMessageFilters(render_process_id); |
214 | 204 |
215 return true; | 205 return true; |
216 } | 206 } |
217 | 207 |
218 void WorkerProcessHost::CreateMessageFilters() { | 208 void WorkerProcessHost::CreateMessageFilters(int render_process_id) { |
219 AddFilter(new AppCacheDispatcherHost(request_context_, id())); | 209 ChromeURLRequestContext* chrome_url_context = GetChromeURLRequestContext(); |
220 AddFilter(new FileSystemDispatcherHost(request_context_)); | 210 |
| 211 worker_message_filter_= new WorkerMessageFilter( |
| 212 render_process_id, |
| 213 request_context_, |
| 214 resource_dispatcher_host(), |
| 215 NewCallbackWithReturnValue( |
| 216 WorkerService::GetInstance(), &WorkerService::next_worker_route_id)); |
| 217 AddFilter(worker_message_filter_); |
| 218 AddFilter(new AppCacheDispatcherHost(chrome_url_context, id())); |
| 219 AddFilter(new FileSystemDispatcherHost(chrome_url_context)); |
221 AddFilter(new FileUtilitiesMessageFilter(id())); | 220 AddFilter(new FileUtilitiesMessageFilter(id())); |
222 AddFilter( | 221 AddFilter( |
223 new BlobMessageFilter(id(), request_context_->blob_storage_context())); | 222 new BlobMessageFilter(id(), chrome_url_context->blob_storage_context())); |
224 AddFilter(new MimeRegistryMessageFilter()); | 223 AddFilter(new MimeRegistryMessageFilter()); |
225 AddFilter(new DatabaseMessageFilter( | 224 AddFilter(new DatabaseMessageFilter( |
226 request_context_->database_tracker(), | 225 chrome_url_context->database_tracker(), |
227 request_context_->host_content_settings_map())); | 226 chrome_url_context->host_content_settings_map())); |
228 | 227 |
229 SocketStreamDispatcherHost* socket_stream_dispatcher_host = | 228 SocketStreamDispatcherHost* socket_stream_dispatcher_host = |
230 new SocketStreamDispatcherHost(); | 229 new SocketStreamDispatcherHost(); |
231 socket_stream_dispatcher_host->set_url_request_context_override( | 230 socket_stream_dispatcher_host->set_url_request_context_override( |
232 new URLRequestContextOverride(request_context_)); | 231 new URLRequestContextOverride(chrome_url_context)); |
233 AddFilter(socket_stream_dispatcher_host); | 232 AddFilter(socket_stream_dispatcher_host); |
234 } | 233 } |
235 | 234 |
236 void WorkerProcessHost::CreateWorker(const WorkerInstance& instance) { | 235 void WorkerProcessHost::CreateWorker(const WorkerInstance& instance) { |
237 ChildProcessSecurityPolicy::GetInstance()->GrantRequestURL( | 236 ChildProcessSecurityPolicy::GetInstance()->GrantRequestURL( |
238 id(), instance.url()); | 237 id(), instance.url()); |
239 | 238 |
240 instances_.push_back(instance); | 239 instances_.push_back(instance); |
241 | 240 |
242 WorkerProcessMsg_CreateWorker_Params params; | 241 WorkerProcessMsg_CreateWorker_Params params; |
243 params.url = instance.url(); | 242 params.url = instance.url(); |
244 params.is_shared = instance.shared(); | 243 params.is_shared = instance.shared(); |
245 params.name = instance.name(); | 244 params.name = instance.name(); |
246 params.route_id = instance.worker_route_id(); | 245 params.route_id = instance.worker_route_id(); |
247 params.creator_process_id = instance.parent_process_id(); | 246 params.creator_process_id = instance.parent_process_id(); |
248 params.creator_appcache_host_id = instance.parent_appcache_host_id(); | 247 params.creator_appcache_host_id = instance.parent_appcache_host_id(); |
249 params.shared_worker_appcache_id = instance.main_resource_appcache_id(); | 248 params.shared_worker_appcache_id = instance.main_resource_appcache_id(); |
250 Send(new WorkerProcessMsg_CreateWorker(params)); | 249 Send(new WorkerProcessMsg_CreateWorker(params)); |
251 | 250 |
252 UpdateTitle(); | 251 UpdateTitle(); |
253 | 252 |
254 // Walk all pending senders and let them know the worker has been created | 253 // Walk all pending filters and let them know the worker has been created |
255 // (could be more than one in the case where we had to queue up worker | 254 // (could be more than one in the case where we had to queue up worker |
256 // creation because the worker process limit was reached). | 255 // creation because the worker process limit was reached). |
257 for (WorkerInstance::SenderList::const_iterator i = | 256 for (WorkerInstance::FilterList::const_iterator i = |
258 instance.senders().begin(); | 257 instance.filters().begin(); |
259 i != instance.senders().end(); ++i) { | 258 i != instance.filters().end(); ++i) { |
260 i->first->Send(new ViewMsg_WorkerCreated(i->second)); | 259 i->first->Send(new ViewMsg_WorkerCreated(i->second)); |
261 } | 260 } |
262 } | 261 } |
263 | 262 |
264 bool WorkerProcessHost::FilterMessage(const IPC::Message& message, | 263 bool WorkerProcessHost::FilterMessage(const IPC::Message& message, |
265 IPC::Message::Sender* sender) { | 264 WorkerMessageFilter* filter) { |
266 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { | 265 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { |
267 if (!i->closed() && i->HasSender(sender, message.routing_id())) { | 266 if (!i->closed() && i->HasFilter(filter, message.routing_id())) { |
268 RelayMessage( | 267 RelayMessage(message, worker_message_filter_, i->worker_route_id()); |
269 message, this, i->worker_route_id(), next_route_id_callback_.get()); | |
270 return true; | 268 return true; |
271 } | 269 } |
272 } | 270 } |
273 | 271 |
274 return false; | 272 return false; |
275 } | 273 } |
276 | 274 |
277 // Sent to notify the browser process when a worker context invokes close(), so | 275 void WorkerProcessHost::OnProcessLaunched() { |
278 // no new connections are sent to shared workers. | |
279 void WorkerProcessHost::OnWorkerContextClosed(int worker_route_id) { | |
280 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { | |
281 if (i->worker_route_id() == worker_route_id) { | |
282 // Set the closed flag - this will stop any further messages from | |
283 // being sent to the worker (messages can still be sent from the worker, | |
284 // for exception reporting, etc). | |
285 i->set_closed(true); | |
286 break; | |
287 } | |
288 } | |
289 } | 276 } |
290 | 277 |
291 void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) { | 278 void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) { |
292 bool msg_is_ok = true; | 279 bool msg_is_ok = true; |
293 bool handled = | 280 bool handled = true; |
294 MessagePortDispatcher::GetInstance()->OnMessageReceived( | 281 IPC_BEGIN_MESSAGE_MAP_EX(WorkerProcessHost, message, msg_is_ok) |
295 message, this, next_route_id_callback_.get(), &msg_is_ok); | 282 IPC_MESSAGE_HANDLER(WorkerHostMsg_WorkerContextClosed, |
296 | 283 OnWorkerContextClosed) |
297 if (!handled) { | 284 IPC_MESSAGE_HANDLER(WorkerProcessHostMsg_AllowDatabase, OnAllowDatabase) |
298 handled = true; | 285 IPC_MESSAGE_UNHANDLED(handled = false) |
299 IPC_BEGIN_MESSAGE_MAP_EX(WorkerProcessHost, message, msg_is_ok) | |
300 IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWorker, OnCreateWorker) | |
301 IPC_MESSAGE_HANDLER(ViewHostMsg_LookupSharedWorker, OnLookupSharedWorker) | |
302 IPC_MESSAGE_HANDLER(ViewHostMsg_CancelCreateDedicatedWorker, | |
303 OnCancelCreateDedicatedWorker) | |
304 IPC_MESSAGE_HANDLER(WorkerHostMsg_WorkerContextClosed, | |
305 OnWorkerContextClosed); | |
306 IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardToWorker, | |
307 OnForwardToWorker) | |
308 IPC_MESSAGE_HANDLER_DELAY_REPLY(WorkerProcessHostMsg_AllowDatabase, | |
309 OnAllowDatabase) | |
310 IPC_MESSAGE_UNHANDLED(handled = false) | |
311 IPC_END_MESSAGE_MAP_EX() | 286 IPC_END_MESSAGE_MAP_EX() |
312 } | |
313 | 287 |
314 if (!msg_is_ok) { | 288 if (!msg_is_ok) { |
315 NOTREACHED(); | 289 NOTREACHED(); |
316 base::KillProcess(handle(), ResultCodes::KILLED_BAD_MESSAGE, false); | 290 base::KillProcess(handle(), ResultCodes::KILLED_BAD_MESSAGE, false); |
317 } | 291 } |
318 | 292 |
319 if (handled) | 293 if (handled) |
320 return; | 294 return; |
321 | 295 |
322 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { | 296 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { |
323 if (i->worker_route_id() == message.routing_id()) { | 297 if (i->worker_route_id() == message.routing_id()) { |
324 if (!i->shared()) { | 298 if (!i->shared()) { |
325 // Don't relay messages from shared workers (all communication is via | 299 // Don't relay messages from shared workers (all communication is via |
326 // the message port). | 300 // the message port). |
327 WorkerInstance::SenderInfo info = i->GetSender(); | 301 WorkerInstance::FilterInfo info = i->GetFilter(); |
328 CallbackWithReturnValue<int>::Type* next_route_id = | 302 RelayMessage(message, info.first, info.second); |
329 GetNextRouteIdCallback(info.first); | |
330 RelayMessage(message, info.first, info.second, next_route_id); | |
331 } | 303 } |
332 | 304 |
333 if (message.type() == WorkerHostMsg_WorkerContextDestroyed::ID) { | 305 if (message.type() == WorkerHostMsg_WorkerContextDestroyed::ID) { |
334 instances_.erase(i); | 306 instances_.erase(i); |
335 UpdateTitle(); | 307 UpdateTitle(); |
336 } | 308 } |
337 break; | 309 break; |
338 } | 310 } |
339 } | 311 } |
340 } | 312 } |
341 | 313 |
342 void WorkerProcessHost::OnProcessLaunched() { | 314 // Sent to notify the browser process when a worker context invokes close(), so |
| 315 // no new connections are sent to shared workers. |
| 316 void WorkerProcessHost::OnWorkerContextClosed(int worker_route_id) { |
| 317 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { |
| 318 if (i->worker_route_id() == worker_route_id) { |
| 319 // Set the closed flag - this will stop any further messages from |
| 320 // being sent to the worker (messages can still be sent from the worker, |
| 321 // for exception reporting, etc). |
| 322 i->set_closed(true); |
| 323 break; |
| 324 } |
| 325 } |
343 } | 326 } |
344 | 327 |
345 CallbackWithReturnValue<int>::Type* WorkerProcessHost::GetNextRouteIdCallback( | 328 void WorkerProcessHost::OnAllowDatabase(int worker_route_id, |
346 IPC::Message::Sender* sender) { | 329 const GURL& url, |
347 // We don't keep callbacks for senders associated with workers, so figure out | 330 const string16& name, |
348 // what kind of sender this is, and cast it to the correct class to get the | 331 const string16& display_name, |
349 // callback. | 332 unsigned long estimated_size, |
350 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); | 333 bool* result) { |
351 !iter.Done(); ++iter) { | 334 ContentSetting content_setting = GetChromeURLRequestContext()-> |
352 WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); | 335 host_content_settings_map()->GetContentSetting( |
353 if (static_cast<IPC::Message::Sender*>(worker) == sender) | 336 url, CONTENT_SETTINGS_TYPE_COOKIES, ""); |
354 return worker->next_route_id_callback_.get(); | 337 |
| 338 *result = content_setting != CONTENT_SETTING_BLOCK; |
| 339 |
| 340 // Find the worker instance and forward the message to all attached documents. |
| 341 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { |
| 342 if (i->worker_route_id() != worker_route_id) |
| 343 continue; |
| 344 const WorkerDocumentSet::DocumentInfoSet& documents = |
| 345 i->worker_document_set()->documents(); |
| 346 for (WorkerDocumentSet::DocumentInfoSet::const_iterator doc = |
| 347 documents.begin(); doc != documents.end(); ++doc) { |
| 348 CallRenderViewHostContentSettingsDelegate( |
| 349 doc->render_process_id(), doc->render_view_id(), |
| 350 &RenderViewHostDelegate::ContentSettings::OnWebDatabaseAccessed, |
| 351 url, name, display_name, estimated_size, !*result); |
| 352 } |
| 353 break; |
355 } | 354 } |
356 | |
357 // Must be a RenderMessageFilter. | |
358 return static_cast<RenderMessageFilter*>(sender)->next_route_id_callback(); | |
359 } | 355 } |
360 | 356 |
361 void WorkerProcessHost::RelayMessage( | 357 void WorkerProcessHost::RelayMessage( |
362 const IPC::Message& message, | 358 const IPC::Message& message, |
363 IPC::Message::Sender* sender, | 359 WorkerMessageFilter* filter, |
364 int route_id, | 360 int route_id) { |
365 CallbackWithReturnValue<int>::Type* next_route_id) { | |
366 | |
367 if (message.type() == WorkerMsg_PostMessage::ID) { | 361 if (message.type() == WorkerMsg_PostMessage::ID) { |
368 // We want to send the receiver a routing id for the new channel, so | 362 // We want to send the receiver a routing id for the new channel, so |
369 // crack the message first. | 363 // crack the message first. |
370 string16 msg; | 364 string16 msg; |
371 std::vector<int> sent_message_port_ids; | 365 std::vector<int> sent_message_port_ids; |
372 std::vector<int> new_routing_ids; | 366 std::vector<int> new_routing_ids; |
373 if (!WorkerMsg_PostMessage::Read( | 367 if (!WorkerMsg_PostMessage::Read( |
374 &message, &msg, &sent_message_port_ids, &new_routing_ids)) { | 368 &message, &msg, &sent_message_port_ids, &new_routing_ids)) { |
375 return; | 369 return; |
376 } | 370 } |
377 if (sent_message_port_ids.size() != new_routing_ids.size()) | 371 if (sent_message_port_ids.size() != new_routing_ids.size()) |
378 return; | 372 return; |
379 | 373 |
380 for (size_t i = 0; i < sent_message_port_ids.size(); ++i) { | 374 for (size_t i = 0; i < sent_message_port_ids.size(); ++i) { |
381 new_routing_ids[i] = next_route_id->Run(); | 375 new_routing_ids[i] = filter->GetNextRoutingID(); |
382 MessagePortDispatcher::GetInstance()->UpdateMessagePort( | 376 MessagePortService::GetInstance()->UpdateMessagePort( |
383 sent_message_port_ids[i], sender, new_routing_ids[i], next_route_id); | 377 sent_message_port_ids[i], filter, new_routing_ids[i]); |
384 } | 378 } |
385 | 379 |
386 sender->Send(new WorkerMsg_PostMessage( | 380 filter->Send(new WorkerMsg_PostMessage( |
387 route_id, msg, sent_message_port_ids, new_routing_ids)); | 381 route_id, msg, sent_message_port_ids, new_routing_ids)); |
388 | 382 |
389 // Send any queued messages to the sent message ports. We can only do this | 383 // Send any queued messages to the sent message ports. We can only do this |
390 // after sending the above message, since it's the one that sets up the | 384 // after sending the above message, since it's the one that sets up the |
391 // message port route which the queued messages are sent to. | 385 // message port route which the queued messages are sent to. |
392 for (size_t i = 0; i < sent_message_port_ids.size(); ++i) { | 386 for (size_t i = 0; i < sent_message_port_ids.size(); ++i) { |
393 MessagePortDispatcher::GetInstance()-> | 387 MessagePortService::GetInstance()-> |
394 SendQueuedMessagesIfPossible(sent_message_port_ids[i]); | 388 SendQueuedMessagesIfPossible(sent_message_port_ids[i]); |
395 } | 389 } |
396 } else if (message.type() == WorkerMsg_Connect::ID) { | 390 } else if (message.type() == WorkerMsg_Connect::ID) { |
397 // Crack the SharedWorker Connect message to setup routing for the port. | 391 // Crack the SharedWorker Connect message to setup routing for the port. |
398 int sent_message_port_id; | 392 int sent_message_port_id; |
399 int new_routing_id; | 393 int new_routing_id; |
400 if (!WorkerMsg_Connect::Read( | 394 if (!WorkerMsg_Connect::Read( |
401 &message, &sent_message_port_id, &new_routing_id)) { | 395 &message, &sent_message_port_id, &new_routing_id)) { |
402 return; | 396 return; |
403 } | 397 } |
404 new_routing_id = next_route_id->Run(); | 398 new_routing_id = filter->GetNextRoutingID(); |
405 MessagePortDispatcher::GetInstance()->UpdateMessagePort( | 399 MessagePortService::GetInstance()->UpdateMessagePort( |
406 sent_message_port_id, sender, new_routing_id, next_route_id); | 400 sent_message_port_id, filter, new_routing_id); |
407 | 401 |
408 // Resend the message with the new routing id. | 402 // Resend the message with the new routing id. |
409 sender->Send(new WorkerMsg_Connect( | 403 filter->Send(new WorkerMsg_Connect( |
410 route_id, sent_message_port_id, new_routing_id)); | 404 route_id, sent_message_port_id, new_routing_id)); |
411 | 405 |
412 // Send any queued messages for the sent port. | 406 // Send any queued messages for the sent port. |
413 MessagePortDispatcher::GetInstance()->SendQueuedMessagesIfPossible( | 407 MessagePortService::GetInstance()->SendQueuedMessagesIfPossible( |
414 sent_message_port_id); | 408 sent_message_port_id); |
415 } else { | 409 } else { |
416 IPC::Message* new_message = new IPC::Message(message); | 410 IPC::Message* new_message = new IPC::Message(message); |
417 new_message->set_routing_id(route_id); | 411 new_message->set_routing_id(route_id); |
418 sender->Send(new_message); | 412 filter->Send(new_message); |
419 return; | 413 return; |
420 } | 414 } |
421 } | 415 } |
422 | 416 |
423 void WorkerProcessHost::SenderShutdown(IPC::Message::Sender* sender) { | 417 void WorkerProcessHost::FilterShutdown(WorkerMessageFilter* filter) { |
424 for (Instances::iterator i = instances_.begin(); i != instances_.end();) { | 418 for (Instances::iterator i = instances_.begin(); i != instances_.end();) { |
425 bool shutdown = false; | 419 bool shutdown = false; |
426 i->RemoveSenders(sender); | 420 i->RemoveFilters(filter); |
427 if (i->shared()) { | 421 if (i->shared()) { |
428 i->worker_document_set()->RemoveAll(sender); | 422 i->worker_document_set()->RemoveAll(filter); |
429 if (i->worker_document_set()->IsEmpty()) { | 423 if (i->worker_document_set()->IsEmpty()) { |
430 shutdown = true; | 424 shutdown = true; |
431 } | 425 } |
432 } else if (i->NumSenders() == 0) { | 426 } else if (i->NumFilters() == 0) { |
433 shutdown = true; | 427 shutdown = true; |
434 } | 428 } |
435 if (shutdown) { | 429 if (shutdown) { |
436 Send(new WorkerMsg_TerminateWorkerContext(i->worker_route_id())); | 430 Send(new WorkerMsg_TerminateWorkerContext(i->worker_route_id())); |
437 i = instances_.erase(i); | 431 i = instances_.erase(i); |
438 } else { | 432 } else { |
439 ++i; | 433 ++i; |
440 } | 434 } |
441 } | 435 } |
442 } | 436 } |
443 | 437 |
444 bool WorkerProcessHost::CanShutdown() { | 438 bool WorkerProcessHost::CanShutdown() { |
445 return instances_.empty(); | 439 return instances_.empty(); |
446 } | 440 } |
447 | 441 |
448 void WorkerProcessHost::UpdateTitle() { | 442 void WorkerProcessHost::UpdateTitle() { |
449 std::set<std::string> titles; | 443 std::set<std::string> titles; |
450 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { | 444 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { |
451 std::string title = | 445 std::string title = |
452 net::RegistryControlledDomainService::GetDomainAndRegistry(i->url()); | 446 net::RegistryControlledDomainService::GetDomainAndRegistry(i->url()); |
453 // Use the host name if the domain is empty, i.e. localhost or IP address. | 447 // Use the host name if the domain is empty, i.e. localhost or IP address. |
454 if (title.empty()) | 448 if (title.empty()) |
455 title = i->url().host(); | 449 title = i->url().host(); |
456 | 450 |
457 // Check if it's an extension-created worker, in which case we want to use | 451 // Check if it's an extension-created worker, in which case we want to use |
458 // the name of the extension. | 452 // the name of the extension. |
459 std::string extension_name = static_cast<ChromeURLRequestContext*>( | 453 std::string extension_name = GetChromeURLRequestContext()-> |
460 Profile::GetDefaultRequestContext()->GetURLRequestContext())-> | |
461 extension_info_map()->GetNameForExtension(title); | 454 extension_info_map()->GetNameForExtension(title); |
462 if (!extension_name.empty()) { | 455 if (!extension_name.empty()) { |
463 titles.insert(extension_name); | 456 titles.insert(extension_name); |
464 continue; | 457 continue; |
465 } | 458 } |
466 | 459 |
467 // If the host name is empty, i.e. file url, use the path. | 460 // If the host name is empty, i.e. file url, use the path. |
468 if (title.empty()) | 461 if (title.empty()) |
469 title = i->url().path(); | 462 title = i->url().path(); |
470 titles.insert(title); | 463 titles.insert(title); |
471 } | 464 } |
472 | 465 |
473 std::string display_title; | 466 std::string display_title; |
474 for (std::set<std::string>::iterator i = titles.begin(); | 467 for (std::set<std::string>::iterator i = titles.begin(); |
475 i != titles.end(); ++i) { | 468 i != titles.end(); ++i) { |
476 if (!display_title.empty()) | 469 if (!display_title.empty()) |
477 display_title += ", "; | 470 display_title += ", "; |
478 display_title += *i; | 471 display_title += *i; |
479 } | 472 } |
480 | 473 |
481 set_name(ASCIIToWide(display_title)); | 474 set_name(ASCIIToWide(display_title)); |
482 } | 475 } |
483 | 476 |
484 void WorkerProcessHost::OnLookupSharedWorker( | 477 ChromeURLRequestContext* WorkerProcessHost::GetChromeURLRequestContext() { |
485 const ViewHostMsg_CreateWorker_Params& params, | 478 return static_cast<ChromeURLRequestContext*>( |
486 bool* exists, | 479 request_context_->GetURLRequestContext()); |
487 int* route_id, | |
488 bool* url_mismatch) { | |
489 *route_id = WorkerService::GetInstance()->next_worker_route_id(); | |
490 // TODO(atwilson): Add code to pass in the current worker's document set for | |
491 // these nested workers. Code below will not work for SharedWorkers as it | |
492 // only looks at a single parent. | |
493 DCHECK(instances_.front().worker_document_set()->documents().size() == 1); | |
494 WorkerDocumentSet::DocumentInfoSet::const_iterator first_parent = | |
495 instances_.front().worker_document_set()->documents().begin(); | |
496 *exists = WorkerService::GetInstance()->LookupSharedWorker( | |
497 params.url, params.name, instances_.front().off_the_record(), | |
498 params.document_id, first_parent->renderer_id(), | |
499 first_parent->render_view_route_id(), this, *route_id, url_mismatch); | |
500 } | 480 } |
501 | 481 |
502 void WorkerProcessHost::OnCreateWorker( | 482 void WorkerProcessHost::DocumentDetached(WorkerMessageFilter* filter, |
503 const ViewHostMsg_CreateWorker_Params& params, int* route_id) { | |
504 DCHECK(instances_.size() == 1); // Only called when one process per worker. | |
505 // TODO(atwilson): Add code to pass in the current worker's document set for | |
506 // these nested workers. Code below will not work for SharedWorkers as it | |
507 // only looks at a single parent. | |
508 DCHECK(instances_.front().worker_document_set()->documents().size() == 1); | |
509 WorkerDocumentSet::DocumentInfoSet::const_iterator first_parent = | |
510 instances_.front().worker_document_set()->documents().begin(); | |
511 *route_id = params.route_id == MSG_ROUTING_NONE ? | |
512 WorkerService::GetInstance()->next_worker_route_id() : params.route_id; | |
513 | |
514 if (params.is_shared) | |
515 WorkerService::GetInstance()->CreateSharedWorker( | |
516 params.url, instances_.front().off_the_record(), | |
517 params.name, params.document_id, first_parent->renderer_id(), | |
518 first_parent->render_view_route_id(), this, *route_id, | |
519 params.script_resource_appcache_id, request_context_); | |
520 else | |
521 WorkerService::GetInstance()->CreateDedicatedWorker( | |
522 params.url, instances_.front().off_the_record(), | |
523 params.document_id, first_parent->renderer_id(), | |
524 first_parent->render_view_route_id(), this, *route_id, | |
525 id(), params.parent_appcache_host_id, request_context_); | |
526 } | |
527 | |
528 void WorkerProcessHost::OnCancelCreateDedicatedWorker(int route_id) { | |
529 WorkerService::GetInstance()->CancelCreateDedicatedWorker(this, route_id); | |
530 } | |
531 | |
532 void WorkerProcessHost::OnForwardToWorker(const IPC::Message& message) { | |
533 WorkerService::GetInstance()->ForwardMessage(message, this); | |
534 } | |
535 | |
536 void WorkerProcessHost::OnAllowDatabase(const GURL& url, | |
537 const string16& name, | |
538 const string16& display_name, | |
539 unsigned long estimated_size, | |
540 IPC::Message* reply_msg) { | |
541 ContentSetting content_setting = | |
542 request_context_->host_content_settings_map()->GetContentSetting( | |
543 url, CONTENT_SETTINGS_TYPE_COOKIES, ""); | |
544 | |
545 bool allowed = content_setting != CONTENT_SETTING_BLOCK; | |
546 | |
547 // Find the worker instance and forward the message to all attached documents. | |
548 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { | |
549 if (i->worker_route_id() != reply_msg->routing_id()) | |
550 continue; | |
551 const WorkerDocumentSet::DocumentInfoSet& documents = | |
552 i->worker_document_set()->documents(); | |
553 for (WorkerDocumentSet::DocumentInfoSet::const_iterator doc = | |
554 documents.begin(); doc != documents.end(); ++doc) { | |
555 CallRenderViewHostContentSettingsDelegate( | |
556 doc->renderer_id(), doc->render_view_route_id(), | |
557 &RenderViewHostDelegate::ContentSettings::OnWebDatabaseAccessed, | |
558 url, name, display_name, estimated_size, !allowed); | |
559 } | |
560 break; | |
561 } | |
562 WorkerProcessHostMsg_AllowDatabase::WriteReplyParams(reply_msg, allowed); | |
563 Send(reply_msg); | |
564 } | |
565 | |
566 void WorkerProcessHost::DocumentDetached(IPC::Message::Sender* parent, | |
567 unsigned long long document_id) { | 483 unsigned long long document_id) { |
568 // Walk all instances and remove the document from their document set. | 484 // Walk all instances and remove the document from their document set. |
569 for (Instances::iterator i = instances_.begin(); i != instances_.end();) { | 485 for (Instances::iterator i = instances_.begin(); i != instances_.end();) { |
570 if (!i->shared()) { | 486 if (!i->shared()) { |
571 ++i; | 487 ++i; |
572 } else { | 488 } else { |
573 i->worker_document_set()->Remove(parent, document_id); | 489 i->worker_document_set()->Remove(filter, document_id); |
574 if (i->worker_document_set()->IsEmpty()) { | 490 if (i->worker_document_set()->IsEmpty()) { |
575 // This worker has no more associated documents - shut it down. | 491 // This worker has no more associated documents - shut it down. |
576 Send(new WorkerMsg_TerminateWorkerContext(i->worker_route_id())); | 492 Send(new WorkerMsg_TerminateWorkerContext(i->worker_route_id())); |
577 i = instances_.erase(i); | 493 i = instances_.erase(i); |
578 } else { | 494 } else { |
579 ++i; | 495 ++i; |
580 } | 496 } |
581 } | 497 } |
582 } | 498 } |
583 } | 499 } |
584 | 500 |
585 WorkerProcessHost::WorkerInstance::WorkerInstance( | 501 WorkerProcessHost::WorkerInstance::WorkerInstance( |
586 const GURL& url, | 502 const GURL& url, |
587 bool shared, | 503 bool shared, |
588 bool off_the_record, | 504 bool off_the_record, |
589 const string16& name, | 505 const string16& name, |
590 int worker_route_id, | 506 int worker_route_id, |
591 int parent_process_id, | 507 int parent_process_id, |
592 int parent_appcache_host_id, | 508 int parent_appcache_host_id, |
593 int64 main_resource_appcache_id, | 509 int64 main_resource_appcache_id, |
594 ChromeURLRequestContext* request_context) | 510 URLRequestContextGetter* request_context) |
595 : url_(url), | 511 : url_(url), |
596 shared_(shared), | 512 shared_(shared), |
597 off_the_record_(off_the_record), | 513 off_the_record_(off_the_record), |
598 closed_(false), | 514 closed_(false), |
599 name_(name), | 515 name_(name), |
600 worker_route_id_(worker_route_id), | 516 worker_route_id_(worker_route_id), |
601 parent_process_id_(parent_process_id), | 517 parent_process_id_(parent_process_id), |
602 parent_appcache_host_id_(parent_appcache_host_id), | 518 parent_appcache_host_id_(parent_appcache_host_id), |
603 main_resource_appcache_id_(main_resource_appcache_id), | 519 main_resource_appcache_id_(main_resource_appcache_id), |
604 request_context_(request_context), | 520 request_context_(request_context), |
605 worker_document_set_(new WorkerDocumentSet()) { | 521 worker_document_set_(new WorkerDocumentSet()) { |
606 DCHECK(!request_context || | |
607 (off_the_record == request_context->is_off_the_record())); | |
608 } | 522 } |
609 | 523 |
610 WorkerProcessHost::WorkerInstance::~WorkerInstance() { | 524 WorkerProcessHost::WorkerInstance::~WorkerInstance() { |
611 } | 525 } |
612 | 526 |
613 // Compares an instance based on the algorithm in the WebWorkers spec - an | 527 // Compares an instance based on the algorithm in the WebWorkers spec - an |
614 // instance matches if the origins of the URLs match, and: | 528 // instance matches if the origins of the URLs match, and: |
615 // a) the names are non-empty and equal | 529 // a) the names are non-empty and equal |
616 // -or- | 530 // -or- |
617 // b) the names are both empty, and the urls are equal | 531 // b) the names are both empty, and the urls are equal |
(...skipping 10 matching lines...) Expand all Loading... |
628 | 542 |
629 if (url_.GetOrigin() != match_url.GetOrigin()) | 543 if (url_.GetOrigin() != match_url.GetOrigin()) |
630 return false; | 544 return false; |
631 | 545 |
632 if (name_.empty() && match_name.empty()) | 546 if (name_.empty() && match_name.empty()) |
633 return url_ == match_url; | 547 return url_ == match_url; |
634 | 548 |
635 return name_ == match_name; | 549 return name_ == match_name; |
636 } | 550 } |
637 | 551 |
638 void WorkerProcessHost::WorkerInstance::AddSender(IPC::Message::Sender* sender, | 552 void WorkerProcessHost::WorkerInstance::AddFilter(WorkerMessageFilter* filter, |
639 int sender_route_id) { | 553 int route_id) { |
640 if (!HasSender(sender, sender_route_id)) { | 554 if (!HasFilter(filter, route_id)) { |
641 SenderInfo info(sender, sender_route_id); | 555 FilterInfo info(filter, route_id); |
642 senders_.push_back(info); | 556 filters_.push_back(info); |
643 } | 557 } |
644 // Only shared workers can have more than one associated sender. | 558 // Only shared workers can have more than one associated filter. |
645 DCHECK(shared_ || senders_.size() == 1); | 559 DCHECK(shared_ || filters_.size() == 1); |
646 } | 560 } |
647 | 561 |
648 void WorkerProcessHost::WorkerInstance::RemoveSender( | 562 void WorkerProcessHost::WorkerInstance::RemoveFilter( |
649 IPC::Message::Sender* sender, int sender_route_id) { | 563 WorkerMessageFilter* filter, int route_id) { |
650 for (SenderList::iterator i = senders_.begin(); i != senders_.end();) { | 564 for (FilterList::iterator i = filters_.begin(); i != filters_.end();) { |
651 if (i->first == sender && i->second == sender_route_id) | 565 if (i->first == filter && i->second == route_id) |
652 i = senders_.erase(i); | 566 i = filters_.erase(i); |
653 else | 567 else |
654 ++i; | 568 ++i; |
655 } | 569 } |
656 // Should not be duplicate copies in the sender set. | 570 // Should not be duplicate copies in the filter set. |
657 DCHECK(!HasSender(sender, sender_route_id)); | 571 DCHECK(!HasFilter(filter, route_id)); |
658 } | 572 } |
659 | 573 |
660 void WorkerProcessHost::WorkerInstance::RemoveSenders( | 574 void WorkerProcessHost::WorkerInstance::RemoveFilters( |
661 IPC::Message::Sender* sender) { | 575 WorkerMessageFilter* filter) { |
662 for (SenderList::iterator i = senders_.begin(); i != senders_.end();) { | 576 for (FilterList::iterator i = filters_.begin(); i != filters_.end();) { |
663 if (i->first == sender) | 577 if (i->first == filter) |
664 i = senders_.erase(i); | 578 i = filters_.erase(i); |
665 else | 579 else |
666 ++i; | 580 ++i; |
667 } | 581 } |
668 } | 582 } |
669 | 583 |
670 bool WorkerProcessHost::WorkerInstance::HasSender( | 584 bool WorkerProcessHost::WorkerInstance::HasFilter( |
671 IPC::Message::Sender* sender, int sender_route_id) const { | 585 WorkerMessageFilter* filter, int route_id) const { |
672 for (SenderList::const_iterator i = senders_.begin(); i != senders_.end(); | 586 for (FilterList::const_iterator i = filters_.begin(); i != filters_.end(); |
673 ++i) { | 587 ++i) { |
674 if (i->first == sender && i->second == sender_route_id) | 588 if (i->first == filter && i->second == route_id) |
675 return true; | 589 return true; |
676 } | 590 } |
677 return false; | 591 return false; |
678 } | 592 } |
679 | 593 |
680 bool WorkerProcessHost::WorkerInstance::RendererIsParent( | 594 bool WorkerProcessHost::WorkerInstance::RendererIsParent( |
681 int renderer_id, int render_view_route_id) const { | 595 int render_process_id, int render_view_id) const { |
682 const WorkerDocumentSet::DocumentInfoSet& parents = | 596 const WorkerDocumentSet::DocumentInfoSet& parents = |
683 worker_document_set()->documents(); | 597 worker_document_set()->documents(); |
684 for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter = | 598 for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter = |
685 parents.begin(); | 599 parents.begin(); |
686 parent_iter != parents.end(); ++parent_iter) { | 600 parent_iter != parents.end(); ++parent_iter) { |
687 if (parent_iter->renderer_id() == renderer_id && | 601 if (parent_iter->render_process_id() == render_process_id && |
688 parent_iter->render_view_route_id() == render_view_route_id) { | 602 parent_iter->render_view_id() == render_view_id) { |
689 return true; | 603 return true; |
690 } | 604 } |
691 } | 605 } |
692 return false; | 606 return false; |
693 } | 607 } |
694 | 608 |
695 WorkerProcessHost::WorkerInstance::SenderInfo | 609 WorkerProcessHost::WorkerInstance::FilterInfo |
696 WorkerProcessHost::WorkerInstance::GetSender() const { | 610 WorkerProcessHost::WorkerInstance::GetFilter() const { |
697 DCHECK(NumSenders() == 1); | 611 DCHECK(NumFilters() == 1); |
698 return *senders_.begin(); | 612 return *filters_.begin(); |
699 } | 613 } |
OLD | NEW |