Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: chrome/browser/worker_host/worker_process_host.cc

Issue 6055002: Create a message filter for message port messages. This allows a nice cleanu... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698