OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/renderer_host/browser_render_process_host.h" | 5 #include "chrome/browser/renderer_host/browser_render_process_host.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <sstream> | 8 #include <sstream> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 | 160 |
161 scoped_refptr<ResourceMessageFilter> resource_message_filter = | 161 scoped_refptr<ResourceMessageFilter> resource_message_filter = |
162 new ResourceMessageFilter(g_browser_process->resource_dispatcher_host(), | 162 new ResourceMessageFilter(g_browser_process->resource_dispatcher_host(), |
163 PluginService::GetInstance(), | 163 PluginService::GetInstance(), |
164 g_browser_process->print_job_manager(), | 164 g_browser_process->print_job_manager(), |
165 host_id(), | 165 host_id(), |
166 profile(), | 166 profile(), |
167 widget_helper_, | 167 widget_helper_, |
168 profile()->GetSpellChecker()); | 168 profile()->GetSpellChecker()); |
169 | 169 |
170 CommandLine browser_command_line; | 170 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
171 | 171 |
172 // setup IPC channel | 172 // setup IPC channel |
173 std::wstring channel_id = GenerateRandomChannelID(this); | 173 std::wstring channel_id = GenerateRandomChannelID(this); |
174 channel_.reset( | 174 channel_.reset( |
175 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_SERVER, this, | 175 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_SERVER, this, |
176 resource_message_filter, | 176 resource_message_filter, |
177 io_thread->message_loop(), true, | 177 io_thread->message_loop(), true, |
178 g_browser_process->shutdown_event())); | 178 g_browser_process->shutdown_event())); |
179 // As a preventive mesure, we DCHECK if someone sends a synchronous message | 179 // As a preventive mesure, we DCHECK if someone sends a synchronous message |
180 // with no time-out, which in the context of the browser process we should not | 180 // with no time-out, which in the context of the browser process we should not |
181 // be doing. | 181 // be doing. |
182 channel_->set_sync_messages_with_no_timeout_allowed(false); | 182 channel_->set_sync_messages_with_no_timeout_allowed(false); |
183 | 183 |
184 // build command line for renderer, we have to quote the executable name to | 184 // build command line for renderer, we have to quote the executable name to |
185 // deal with spaces | 185 // deal with spaces |
186 std::wstring renderer_path = | 186 std::wstring renderer_path = |
187 browser_command_line.GetSwitchValue(switches::kRendererPath); | 187 browser_command_line.GetSwitchValue(switches::kRendererPath); |
188 if (renderer_path.empty()) | 188 if (renderer_path.empty()) |
189 if (!GetRendererPath(&renderer_path)) | 189 if (!GetRendererPath(&renderer_path)) |
190 return false; | 190 return false; |
191 std::wstring cmd_line; | 191 CommandLine cmd_line(renderer_path); |
192 cmd_line = L"\"" + renderer_path + L"\""; | |
193 if (logging::DialogsAreSuppressed()) | 192 if (logging::DialogsAreSuppressed()) |
194 CommandLine::AppendSwitch(&cmd_line, switches::kNoErrorDialogs); | 193 cmd_line.AppendSwitch(switches::kNoErrorDialogs); |
195 | 194 |
196 // propagate the following switches to the renderer command line | 195 // propagate the following switches to the renderer command line |
197 // (along with any associated values) if present in the browser command line | 196 // (along with any associated values) if present in the browser command line |
198 static const wchar_t* const switch_names[] = { | 197 static const wchar_t* const switch_names[] = { |
199 switches::kRendererAssertTest, | 198 switches::kRendererAssertTest, |
200 switches::kRendererCrashTest, | 199 switches::kRendererCrashTest, |
201 switches::kRendererStartupDialog, | 200 switches::kRendererStartupDialog, |
202 switches::kNoSandbox, | 201 switches::kNoSandbox, |
203 switches::kTestSandbox, | 202 switches::kTestSandbox, |
204 switches::kInProcessPlugins, | 203 switches::kInProcessPlugins, |
(...skipping 17 matching lines...) Expand all Loading... |
222 switches::kSilentDumpOnDCHECK, | 221 switches::kSilentDumpOnDCHECK, |
223 switches::kDisablePopupBlocking, | 222 switches::kDisablePopupBlocking, |
224 switches::kUseLowFragHeapCrt, | 223 switches::kUseLowFragHeapCrt, |
225 switches::kGearsInRenderer, | 224 switches::kGearsInRenderer, |
226 switches::kEnableUserScripts, | 225 switches::kEnableUserScripts, |
227 switches::kEnableVideo, | 226 switches::kEnableVideo, |
228 }; | 227 }; |
229 | 228 |
230 for (int i = 0; i < arraysize(switch_names); ++i) { | 229 for (int i = 0; i < arraysize(switch_names); ++i) { |
231 if (browser_command_line.HasSwitch(switch_names[i])) { | 230 if (browser_command_line.HasSwitch(switch_names[i])) { |
232 CommandLine::AppendSwitchWithValue( | 231 cmd_line.AppendSwitchWithValue(switch_names[i], |
233 &cmd_line, switch_names[i], | |
234 browser_command_line.GetSwitchValue(switch_names[i])); | 232 browser_command_line.GetSwitchValue(switch_names[i])); |
235 } | 233 } |
236 } | 234 } |
237 | 235 |
238 // Pass on the browser locale. | 236 // Pass on the browser locale. |
239 const std::wstring locale = g_browser_process->GetApplicationLocale(); | 237 const std::wstring locale = g_browser_process->GetApplicationLocale(); |
240 CommandLine::AppendSwitchWithValue(&cmd_line, switches::kLang, locale); | 238 cmd_line.AppendSwitchWithValue(switches::kLang, locale); |
241 | 239 |
242 bool in_sandbox = !browser_command_line.HasSwitch(switches::kNoSandbox); | 240 bool in_sandbox = !browser_command_line.HasSwitch(switches::kNoSandbox); |
243 if (browser_command_line.HasSwitch(switches::kInProcessPlugins)) { | 241 if (browser_command_line.HasSwitch(switches::kInProcessPlugins)) { |
244 // In process plugins won't work if the sandbox is enabled. | 242 // In process plugins won't work if the sandbox is enabled. |
245 in_sandbox = false; | 243 in_sandbox = false; |
246 } | 244 } |
247 | 245 |
248 bool child_needs_help = | 246 bool child_needs_help = |
249 DebugFlags::ProcessDebugFlags(&cmd_line, | 247 DebugFlags::ProcessDebugFlags(&cmd_line, |
250 DebugFlags::RENDERER, | 248 DebugFlags::RENDERER, |
251 in_sandbox); | 249 in_sandbox); |
252 CommandLine::AppendSwitchWithValue(&cmd_line, | 250 cmd_line.AppendSwitchWithValue(switches::kProcessType, |
253 switches::kProcessType, | 251 switches::kRendererProcess); |
254 switches::kRendererProcess); | |
255 | 252 |
256 CommandLine::AppendSwitchWithValue(&cmd_line, | 253 cmd_line.AppendSwitchWithValue(switches::kProcessChannelID, |
257 switches::kProcessChannelID, | 254 channel_id); |
258 channel_id); | |
259 | 255 |
260 const std::wstring& profile_path = | 256 const std::wstring& profile_path = |
261 browser_command_line.GetSwitchValue(switches::kUserDataDir); | 257 browser_command_line.GetSwitchValue(switches::kUserDataDir); |
262 if (!profile_path.empty()) | 258 if (!profile_path.empty()) |
263 CommandLine::AppendSwitchWithValue(&cmd_line, switches::kUserDataDir, | 259 cmd_line.AppendSwitchWithValue(switches::kUserDataDir, |
264 profile_path); | 260 profile_path); |
265 | 261 |
266 bool run_in_process = run_renderer_in_process(); | 262 bool run_in_process = run_renderer_in_process(); |
267 if (run_in_process) { | 263 if (run_in_process) { |
268 // Crank up a thread and run the initialization there. With the way that | 264 // Crank up a thread and run the initialization there. With the way that |
269 // messages flow between the browser and renderer, this thread is required | 265 // messages flow between the browser and renderer, this thread is required |
270 // to prevent a deadlock in single-process mode. When using multiple | 266 // to prevent a deadlock in single-process mode. When using multiple |
271 // processes, the primordial thread in the renderer process has a message | 267 // processes, the primordial thread in the renderer process has a message |
272 // loop which is used for sending messages asynchronously to the io thread | 268 // loop which is used for sending messages asynchronously to the io thread |
273 // in the browser process. If we don't create this thread, then the | 269 // in the browser process. If we don't create this thread, then the |
274 // RenderThread is both responsible for rendering and also for | 270 // RenderThread is both responsible for rendering and also for |
275 // communicating IO. This can lead to deadlocks where the RenderThread is | 271 // communicating IO. This can lead to deadlocks where the RenderThread is |
276 // waiting for the IO to complete, while the browsermain is trying to pass | 272 // waiting for the IO to complete, while the browsermain is trying to pass |
277 // an event to the RenderThread. | 273 // an event to the RenderThread. |
278 // | 274 // |
279 // TODO: We should consider how to better cleanup threads on exit. | 275 // TODO: We should consider how to better cleanup threads on exit. |
280 base::Thread *render_thread = new RendererMainThread(channel_id); | 276 base::Thread *render_thread = new RendererMainThread(channel_id); |
281 base::Thread::Options options; | 277 base::Thread::Options options; |
282 options.message_loop_type = MessageLoop::TYPE_IO; | 278 options.message_loop_type = MessageLoop::TYPE_IO; |
283 render_thread->StartWithOptions(options); | 279 render_thread->StartWithOptions(options); |
284 } else { | 280 } else { |
285 if (g_browser_process->local_state() && | 281 if (g_browser_process->local_state() && |
286 g_browser_process->local_state()->GetBoolean( | 282 g_browser_process->local_state()->GetBoolean( |
287 prefs::kStartRenderersManually)) { | 283 prefs::kStartRenderersManually)) { |
288 std::wstring message = | 284 std::wstring message = |
289 L"Please start a renderer process using:\n" + cmd_line; | 285 L"Please start a renderer process using:\n" + |
| 286 cmd_line.command_line_string(); |
290 | 287 |
291 // We don't know the owner window for BrowserRenderProcessHost and therefo
re we | 288 // We don't know the owner window for BrowserRenderProcessHost and therefo
re we |
292 // pass a NULL HWND argument. | 289 // pass a NULL HWND argument. |
293 win_util::MessageBox(NULL, | 290 win_util::MessageBox(NULL, |
294 message, | 291 message, |
295 switches::kBrowserStartRenderersManually, | 292 switches::kBrowserStartRenderersManually, |
296 MB_OK); | 293 MB_OK); |
297 } else { | 294 } else { |
298 if (in_sandbox) { | 295 if (in_sandbox) { |
299 // spawn the child process in the sandbox | 296 // spawn the child process in the sandbox |
(...skipping 21 matching lines...) Expand all Loading... |
321 policy->SetDesktop(kDesktopName); | 318 policy->SetDesktop(kDesktopName); |
322 } else { | 319 } else { |
323 DLOG(WARNING) << "Failed to apply desktop security to the renderer"; | 320 DLOG(WARNING) << "Failed to apply desktop security to the renderer"; |
324 } | 321 } |
325 | 322 |
326 if (!AddGenericPolicy(policy)) { | 323 if (!AddGenericPolicy(policy)) { |
327 NOTREACHED(); | 324 NOTREACHED(); |
328 return false; | 325 return false; |
329 } | 326 } |
330 | 327 |
331 CommandLine command_line; | 328 if (browser_command_line.HasSwitch(switches::kGearsInRenderer)) { |
332 if (command_line.HasSwitch(switches::kGearsInRenderer)) { | |
333 if (!AddPolicyForGearsInRenderer(policy)) { | 329 if (!AddPolicyForGearsInRenderer(policy)) { |
334 NOTREACHED(); | 330 NOTREACHED(); |
335 return false; | 331 return false; |
336 } | 332 } |
337 } | 333 } |
338 | 334 |
339 if (!AddDllEvictionPolicy(policy)) { | 335 if (!AddDllEvictionPolicy(policy)) { |
340 NOTREACHED(); | 336 NOTREACHED(); |
341 return false; | 337 return false; |
342 } | 338 } |
343 | 339 |
344 result = broker_service->SpawnTarget(renderer_path.c_str(), | 340 result = |
345 cmd_line.c_str(), | 341 broker_service->SpawnTarget(renderer_path.c_str(), |
346 policy, &target); | 342 cmd_line.command_line_string().c_str(), |
| 343 policy, &target); |
347 policy->Release(); | 344 policy->Release(); |
348 | 345 |
349 if (desktop) | 346 if (desktop) |
350 CloseDesktop(desktop); | 347 CloseDesktop(desktop); |
351 | 348 |
352 if (sandbox::SBOX_ALL_OK != result) | 349 if (sandbox::SBOX_ALL_OK != result) |
353 return false; | 350 return false; |
354 | 351 |
355 bool on_sandbox_desktop = (desktop != NULL); | 352 bool on_sandbox_desktop = (desktop != NULL); |
356 NotificationService::current()->Notify( | 353 NotificationService::current()->Notify( |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 base::SharedMemoryHandle handle_for_process = NULL; | 455 base::SharedMemoryHandle handle_for_process = NULL; |
459 visitedlink_master->ShareToProcess(GetRendererProcessHandle(), | 456 visitedlink_master->ShareToProcess(GetRendererProcessHandle(), |
460 &handle_for_process); | 457 &handle_for_process); |
461 DCHECK(handle_for_process); | 458 DCHECK(handle_for_process); |
462 if (handle_for_process) { | 459 if (handle_for_process) { |
463 channel_->Send(new ViewMsg_VisitedLink_NewTable(handle_for_process)); | 460 channel_->Send(new ViewMsg_VisitedLink_NewTable(handle_for_process)); |
464 } | 461 } |
465 } | 462 } |
466 | 463 |
467 void BrowserRenderProcessHost::InitUserScripts() { | 464 void BrowserRenderProcessHost::InitUserScripts() { |
468 CommandLine command_line; | 465 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
469 if (!command_line.HasSwitch(switches::kEnableUserScripts)) { | 466 switches::kEnableUserScripts)) { |
470 return; | 467 return; |
471 } | 468 } |
472 | 469 |
473 // TODO(aa): Figure out lifetime and ownership of this object | 470 // TODO(aa): Figure out lifetime and ownership of this object |
474 // - VisitedLinkMaster is owned by Profile, but there has been talk of | 471 // - VisitedLinkMaster is owned by Profile, but there has been talk of |
475 // having scripts live elsewhere besides the profile. | 472 // having scripts live elsewhere besides the profile. |
476 // - File IO should be asynchronous (see VisitedLinkMaster), but how do we | 473 // - File IO should be asynchronous (see VisitedLinkMaster), but how do we |
477 // get scripts to the first renderer without blocking startup? Should we | 474 // get scripts to the first renderer without blocking startup? Should we |
478 // cache some information across restarts? | 475 // cache some information across restarts? |
479 UserScriptMaster* user_script_master = profile()->GetUserScriptMaster(); | 476 UserScriptMaster* user_script_master = profile()->GetUserScriptMaster(); |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 SendUserScriptsUpdate(shared_memory); | 718 SendUserScriptsUpdate(shared_memory); |
722 } | 719 } |
723 break; | 720 break; |
724 } | 721 } |
725 default: { | 722 default: { |
726 NOTREACHED(); | 723 NOTREACHED(); |
727 break; | 724 break; |
728 } | 725 } |
729 } | 726 } |
730 } | 727 } |
OLD | NEW |