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 // Represents the browser side of the browser <--> renderer communication | 5 // Represents the browser side of the browser <--> renderer communication |
6 // channel. There will be one RenderProcessHost per renderer process. | 6 // channel. There will be one RenderProcessHost per renderer process. |
7 | 7 |
8 #include "chrome/browser/renderer_host/browser_render_process_host.h" | 8 #include "chrome/browser/renderer_host/browser_render_process_host.h" |
9 | 9 |
10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 const int32 kInvalidViewID = -1; | 114 const int32 kInvalidViewID = -1; |
115 | 115 |
116 // Get the path to the renderer executable, which is the same as the | 116 // Get the path to the renderer executable, which is the same as the |
117 // current executable. | 117 // current executable. |
118 bool GetRendererPath(std::wstring* cmd_line) { | 118 bool GetRendererPath(std::wstring* cmd_line) { |
119 return PathService::Get(base::FILE_EXE, cmd_line); | 119 return PathService::Get(base::FILE_EXE, cmd_line); |
120 } | 120 } |
121 | 121 |
122 const wchar_t* const kDesktopName = L"ChromeRendererDesktop"; | 122 const wchar_t* const kDesktopName = L"ChromeRendererDesktop"; |
123 | 123 |
124 // static | |
125 void BrowserRenderProcessHost::RegisterPrefs(PrefService* prefs) { | |
126 prefs->RegisterBooleanPref(prefs::kStartRenderersManually, false); | |
127 } | |
128 | |
129 BrowserRenderProcessHost::BrowserRenderProcessHost(Profile* profile) | 124 BrowserRenderProcessHost::BrowserRenderProcessHost(Profile* profile) |
130 : RenderProcessHost(profile), | 125 : RenderProcessHost(profile), |
131 visible_widgets_(0), | 126 visible_widgets_(0), |
132 backgrounded_(true), | 127 backgrounded_(true), |
133 ALLOW_THIS_IN_INITIALIZER_LIST(cached_dibs_cleaner_( | 128 ALLOW_THIS_IN_INITIALIZER_LIST(cached_dibs_cleaner_( |
134 base::TimeDelta::FromSeconds(5), | 129 base::TimeDelta::FromSeconds(5), |
135 this, &BrowserRenderProcessHost::ClearTransportDIBCache)) { | 130 this, &BrowserRenderProcessHost::ClearTransportDIBCache)) { |
136 DCHECK(host_id() >= 0); // We use a negative host_id_ in destruction. | 131 DCHECK(host_id() >= 0); // We use a negative host_id_ in destruction. |
137 widget_helper_ = new RenderWidgetHelper(host_id()); | 132 widget_helper_ = new RenderWidgetHelper(host_id()); |
138 | 133 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 } | 166 } |
172 | 167 |
173 profile()->GetPrefs()->RemovePrefObserver(prefs::kBlockPopups, this); | 168 profile()->GetPrefs()->RemovePrefObserver(prefs::kBlockPopups, this); |
174 | 169 |
175 NotificationService::current()->RemoveObserver(this, | 170 NotificationService::current()->RemoveObserver(this, |
176 NotificationType::USER_SCRIPTS_LOADED, NotificationService::AllSources()); | 171 NotificationType::USER_SCRIPTS_LOADED, NotificationService::AllSources()); |
177 | 172 |
178 ClearTransportDIBCache(); | 173 ClearTransportDIBCache(); |
179 } | 174 } |
180 | 175 |
181 // When we're started with the --start-renderers-manually flag, we pop up a | |
182 // modal dialog requesting the user manually start up a renderer. | |
183 // |cmd_line| is the command line to start the renderer with. | |
184 static void RunStartRenderersManuallyDialog(const CommandLine& cmd_line) { | |
185 #if defined(OS_WIN) | |
186 std::wstring message = | |
187 L"Please start a renderer process using:\n" + | |
188 cmd_line.command_line_string(); | |
189 | |
190 // We don't know the owner window for RenderProcessHost and therefore we | |
191 // pass a NULL HWND argument. | |
192 win_util::MessageBox(NULL, | |
193 message, | |
194 switches::kBrowserStartRenderersManually, | |
195 MB_OK); | |
196 #else | |
197 // TODO(port): refactor above code / pop up a message box here. | |
198 NOTIMPLEMENTED(); | |
199 #endif | |
200 } | |
201 | |
202 bool BrowserRenderProcessHost::Init() { | 176 bool BrowserRenderProcessHost::Init() { |
203 // calling Init() more than once does nothing, this makes it more convenient | 177 // calling Init() more than once does nothing, this makes it more convenient |
204 // for the view host which may not be sure in some cases | 178 // for the view host which may not be sure in some cases |
205 if (channel_.get()) | 179 if (channel_.get()) |
206 return true; | 180 return true; |
207 | 181 |
208 // run the IPC channel on the shared IO thread. | 182 // run the IPC channel on the shared IO thread. |
209 base::Thread* io_thread = g_browser_process->io_thread(); | 183 base::Thread* io_thread = g_browser_process->io_thread(); |
210 | 184 |
211 // Construct the AudioRendererHost with the IO thread. | 185 // Construct the AudioRendererHost with the IO thread. |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 // RenderThread is both responsible for rendering and also for | 316 // RenderThread is both responsible for rendering and also for |
343 // communicating IO. This can lead to deadlocks where the RenderThread is | 317 // communicating IO. This can lead to deadlocks where the RenderThread is |
344 // waiting for the IO to complete, while the browsermain is trying to pass | 318 // waiting for the IO to complete, while the browsermain is trying to pass |
345 // an event to the RenderThread. | 319 // an event to the RenderThread. |
346 in_process_renderer_.reset(new RendererMainThread(channel_id)); | 320 in_process_renderer_.reset(new RendererMainThread(channel_id)); |
347 | 321 |
348 base::Thread::Options options; | 322 base::Thread::Options options; |
349 options.message_loop_type = MessageLoop::TYPE_IO; | 323 options.message_loop_type = MessageLoop::TYPE_IO; |
350 in_process_renderer_->StartWithOptions(options); | 324 in_process_renderer_->StartWithOptions(options); |
351 } else { | 325 } else { |
352 if (g_browser_process->local_state() && | |
353 g_browser_process->local_state()->GetBoolean( | |
354 prefs::kStartRenderersManually)) { | |
355 RunStartRenderersManuallyDialog(cmd_line); | |
356 } else { | |
357 #if defined(OS_WIN) | 326 #if defined(OS_WIN) |
358 if (in_sandbox) { | 327 if (in_sandbox) { |
359 // spawn the child process in the sandbox | 328 // spawn the child process in the sandbox |
360 sandbox::BrokerServices* broker_service = | 329 sandbox::BrokerServices* broker_service = |
361 g_browser_process->broker_services(); | 330 g_browser_process->broker_services(); |
362 | 331 |
363 sandbox::ResultCode result; | 332 sandbox::ResultCode result; |
364 PROCESS_INFORMATION target = {0}; | 333 PROCESS_INFORMATION target = {0}; |
365 sandbox::TargetPolicy* policy = broker_service->CreatePolicy(); | 334 sandbox::TargetPolicy* policy = broker_service->CreatePolicy(); |
366 policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0); | 335 policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0); |
367 | 336 |
368 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; | 337 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; |
369 if (win_util::GetWinVersion() > win_util::WINVERSION_XP) { | 338 if (win_util::GetWinVersion() > win_util::WINVERSION_XP) { |
370 // On 2003/Vista the initial token has to be restricted if the main | 339 // On 2003/Vista the initial token has to be restricted if the main |
371 // token is restricted. | 340 // token is restricted. |
372 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; | 341 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; |
373 } | 342 } |
374 | 343 |
375 policy->SetTokenLevel(initial_token, sandbox::USER_LOCKDOWN); | 344 policy->SetTokenLevel(initial_token, sandbox::USER_LOCKDOWN); |
376 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); | 345 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); |
377 | 346 |
378 HDESK desktop = CreateDesktop(kDesktopName, NULL, NULL, 0, | 347 HDESK desktop = CreateDesktop(kDesktopName, NULL, NULL, 0, |
379 DESKTOP_CREATEWINDOW, NULL); | 348 DESKTOP_CREATEWINDOW, NULL); |
380 if (desktop) { | 349 if (desktop) { |
381 policy->SetDesktop(kDesktopName); | 350 policy->SetDesktop(kDesktopName); |
382 } else { | 351 } else { |
383 DLOG(WARNING) << "Failed to apply desktop security to the renderer"; | 352 DLOG(WARNING) << "Failed to apply desktop security to the renderer"; |
384 } | 353 } |
385 | 354 |
386 if (!AddGenericPolicy(policy)) { | 355 if (!AddGenericPolicy(policy)) { |
| 356 NOTREACHED(); |
| 357 return false; |
| 358 } |
| 359 |
| 360 if (browser_command_line.HasSwitch(switches::kGearsInRenderer)) { |
| 361 if (!AddPolicyForGearsInRenderer(policy)) { |
387 NOTREACHED(); | 362 NOTREACHED(); |
388 return false; | 363 return false; |
389 } | 364 } |
| 365 } |
390 | 366 |
391 if (browser_command_line.HasSwitch(switches::kGearsInRenderer)) { | 367 if (!AddDllEvictionPolicy(policy)) { |
392 if (!AddPolicyForGearsInRenderer(policy)) { | 368 NOTREACHED(); |
393 NOTREACHED(); | 369 return false; |
394 return false; | 370 } |
395 } | |
396 } | |
397 | 371 |
398 if (!AddDllEvictionPolicy(policy)) { | 372 result = |
399 NOTREACHED(); | 373 broker_service->SpawnTarget(renderer_path.c_str(), |
400 return false; | 374 cmd_line.command_line_string().c_str(), |
401 } | 375 policy, &target); |
| 376 policy->Release(); |
402 | 377 |
403 result = | 378 if (desktop) |
404 broker_service->SpawnTarget(renderer_path.c_str(), | 379 CloseDesktop(desktop); |
405 cmd_line.command_line_string().c_str(), | |
406 policy, &target); | |
407 policy->Release(); | |
408 | 380 |
409 if (desktop) | 381 if (sandbox::SBOX_ALL_OK != result) |
410 CloseDesktop(desktop); | 382 return false; |
411 | 383 |
412 if (sandbox::SBOX_ALL_OK != result) | 384 bool on_sandbox_desktop = (desktop != NULL); |
413 return false; | 385 NotificationService::current()->Notify( |
| 386 NotificationType::RENDERER_PROCESS_IN_SBOX, |
| 387 Source<BrowserRenderProcessHost>(this), |
| 388 Details<bool>(&on_sandbox_desktop)); |
414 | 389 |
415 bool on_sandbox_desktop = (desktop != NULL); | 390 ResumeThread(target.hThread); |
416 NotificationService::current()->Notify( | 391 CloseHandle(target.hThread); |
417 NotificationType::RENDERER_PROCESS_IN_SBOX, | 392 process_.set_handle(target.hProcess); |
418 Source<BrowserRenderProcessHost>(this), | |
419 Details<bool>(&on_sandbox_desktop)); | |
420 | 393 |
421 ResumeThread(target.hThread); | 394 // Help the process a little. It can't start the debugger by itself if |
422 CloseHandle(target.hThread); | 395 // the process is in a sandbox. |
423 process_.set_handle(target.hProcess); | 396 if (child_needs_help) |
424 | 397 DebugUtil::SpawnDebuggerOnProcess(target.dwProcessId); |
425 // Help the process a little. It can't start the debugger by itself if | 398 } else |
426 // the process is in a sandbox. | |
427 if (child_needs_help) | |
428 DebugUtil::SpawnDebuggerOnProcess(target.dwProcessId); | |
429 } else | |
430 #endif // OS_WIN and sandbox | 399 #endif // OS_WIN and sandbox |
431 { | 400 { |
432 // spawn child process | 401 // spawn child process |
433 base::ProcessHandle process = 0; | 402 base::ProcessHandle process = 0; |
434 if (!SpawnChild(cmd_line, channel_.get(), &process)) | 403 if (!SpawnChild(cmd_line, channel_.get(), &process)) |
435 return false; | 404 return false; |
436 process_.set_handle(process); | 405 process_.set_handle(process); |
437 } | |
438 } | 406 } |
439 } | 407 } |
440 | 408 |
441 // Now that the process is created, set it's backgrounding accordingly. | 409 // Now that the process is created, set it's backgrounding accordingly. |
442 SetBackgrounded(backgrounded_); | 410 SetBackgrounded(backgrounded_); |
443 | 411 |
444 InitVisitedLinks(); | 412 InitVisitedLinks(); |
445 InitUserScripts(); | 413 InitUserScripts(); |
446 | 414 |
447 if (max_page_id_ != -1) | 415 if (max_page_id_ != -1) |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 SendUserScriptsUpdate(shared_memory); | 865 SendUserScriptsUpdate(shared_memory); |
898 } | 866 } |
899 break; | 867 break; |
900 } | 868 } |
901 default: { | 869 default: { |
902 NOTREACHED(); | 870 NOTREACHED(); |
903 break; | 871 break; |
904 } | 872 } |
905 } | 873 } |
906 } | 874 } |
OLD | NEW |