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

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

Powered by Google App Engine
This is Rietveld 408576698