Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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 "content/browser/renderer_host/render_process_host_impl.h" | 8 #include "content/browser/renderer_host/render_process_host_impl.h" |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 473 StoragePartitionImpl* storage_partition_impl, | 473 StoragePartitionImpl* storage_partition_impl, |
| 474 bool is_for_guests_only) | 474 bool is_for_guests_only) |
| 475 : fast_shutdown_started_(false), | 475 : fast_shutdown_started_(false), |
| 476 deleting_soon_(false), | 476 deleting_soon_(false), |
| 477 #ifndef NDEBUG | 477 #ifndef NDEBUG |
| 478 is_self_deleted_(false), | 478 is_self_deleted_(false), |
| 479 #endif | 479 #endif |
| 480 pending_views_(0), | 480 pending_views_(0), |
| 481 mojo_application_host_(new MojoApplicationHost), | 481 mojo_application_host_(new MojoApplicationHost), |
| 482 visible_widgets_(0), | 482 visible_widgets_(0), |
| 483 backgrounded_(true), | 483 is_process_backgrounded_(false), |
| 484 is_initialized_(false), | 484 is_initialized_(false), |
| 485 id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), | 485 id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), |
| 486 browser_context_(browser_context), | 486 browser_context_(browser_context), |
| 487 storage_partition_impl_(storage_partition_impl), | 487 storage_partition_impl_(storage_partition_impl), |
| 488 sudden_termination_allowed_(true), | 488 sudden_termination_allowed_(true), |
| 489 ignore_input_events_(false), | 489 ignore_input_events_(false), |
| 490 is_for_guests_only_(is_for_guests_only), | 490 is_for_guests_only_(is_for_guests_only), |
| 491 gpu_observer_registered_(false), | 491 gpu_observer_registered_(false), |
| 492 delayed_cleanup_needed_(false), | 492 delayed_cleanup_needed_(false), |
| 493 within_process_died_observer_(false), | 493 within_process_died_observer_(false), |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 511 if (!GetBrowserContext()->IsOffTheRecord() && | 511 if (!GetBrowserContext()->IsOffTheRecord() && |
| 512 !base::CommandLine::ForCurrentProcess()->HasSwitch( | 512 !base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 513 switches::kDisableGpuShaderDiskCache)) { | 513 switches::kDisableGpuShaderDiskCache)) { |
| 514 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 514 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 515 base::Bind(&CacheShaderInfo, GetID(), | 515 base::Bind(&CacheShaderInfo, GetID(), |
| 516 storage_partition_impl_->GetPath())); | 516 storage_partition_impl_->GetPath())); |
| 517 } | 517 } |
| 518 subscribe_uniform_enabled_ = | 518 subscribe_uniform_enabled_ = |
| 519 base::CommandLine::ForCurrentProcess()->HasSwitch( | 519 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 520 switches::kEnableSubscribeUniformExtension); | 520 switches::kEnableSubscribeUniformExtension); |
| 521 | |
| 522 // Note: When we create the RenderProcessHostImpl, it's technically | |
| 523 // backgrounded, because it has no visible listeners. But the process | |
| 524 // doesn't actually exist yet, so we'll Background it later, after | |
| 525 // creation. | |
| 526 } | 521 } |
| 527 | 522 |
| 528 // static | 523 // static |
| 529 void RenderProcessHostImpl::ShutDownInProcessRenderer() { | 524 void RenderProcessHostImpl::ShutDownInProcessRenderer() { |
| 530 DCHECK(g_run_renderer_in_process_); | 525 DCHECK(g_run_renderer_in_process_); |
| 531 | 526 |
| 532 switch (g_all_hosts.Pointer()->size()) { | 527 switch (g_all_hosts.Pointer()->size()) { |
| 533 case 0: | 528 case 0: |
| 534 return; | 529 return; |
| 535 case 1: { | 530 case 1: { |
| (...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1064 // crash. | 1059 // crash. |
| 1065 CHECK(false); | 1060 CHECK(false); |
| 1066 } | 1061 } |
| 1067 // We kill the renderer but don't include a NOTREACHED, because we want the | 1062 // We kill the renderer but don't include a NOTREACHED, because we want the |
| 1068 // browser to try to survive when it gets illegal messages from the renderer. | 1063 // browser to try to survive when it gets illegal messages from the renderer. |
| 1069 Shutdown(RESULT_CODE_KILLED_BAD_MESSAGE, false); | 1064 Shutdown(RESULT_CODE_KILLED_BAD_MESSAGE, false); |
| 1070 } | 1065 } |
| 1071 | 1066 |
| 1072 void RenderProcessHostImpl::WidgetRestored() { | 1067 void RenderProcessHostImpl::WidgetRestored() { |
| 1073 // Verify we were properly backgrounded. | 1068 // Verify we were properly backgrounded. |
| 1074 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0)); | |
| 1075 visible_widgets_++; | 1069 visible_widgets_++; |
| 1076 SetBackgrounded(false); | 1070 UpdateProcessPriority(); |
| 1071 DCHECK(!is_process_backgrounded_); | |
| 1077 } | 1072 } |
| 1078 | 1073 |
| 1079 void RenderProcessHostImpl::WidgetHidden() { | 1074 void RenderProcessHostImpl::WidgetHidden() { |
| 1080 // On startup, the browser will call Hide | 1075 // On startup, the browser will call Hide. We ignore these calls. |
| 1081 if (backgrounded_) | 1076 if (visible_widgets_ == 0) |
| 1082 return; | 1077 return; |
| 1083 | 1078 |
| 1084 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0)); | 1079 DCHECK_GE(visible_widgets_, 1); |
|
gab
2015/07/08 18:50:56
DCHECK_GT(visible_wigets, 0);
slightly better IM
| |
| 1085 visible_widgets_--; | 1080 if (--visible_widgets_ == 0) { |
| 1086 DCHECK_GE(visible_widgets_, 0); | 1081 DCHECK(!is_process_backgrounded_); |
| 1087 if (visible_widgets_ == 0) { | 1082 UpdateProcessPriority(); |
| 1088 DCHECK(!backgrounded_); | |
| 1089 SetBackgrounded(true); | |
| 1090 } | 1083 } |
| 1091 } | 1084 } |
| 1092 | 1085 |
| 1093 int RenderProcessHostImpl::VisibleWidgetCount() const { | 1086 int RenderProcessHostImpl::VisibleWidgetCount() const { |
| 1094 return visible_widgets_; | 1087 return visible_widgets_; |
| 1095 } | 1088 } |
| 1096 | 1089 |
| 1097 bool RenderProcessHostImpl::IsForGuestsOnly() const { | 1090 bool RenderProcessHostImpl::IsForGuestsOnly() const { |
| 1098 return is_for_guests_only_; | 1091 return is_for_guests_only_; |
| 1099 } | 1092 } |
| (...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2109 | 2102 |
| 2110 RendererClosedDetails details(status, exit_code); | 2103 RendererClosedDetails details(status, exit_code); |
| 2111 mojo_application_host_->WillDestroySoon(); | 2104 mojo_application_host_->WillDestroySoon(); |
| 2112 | 2105 |
| 2113 child_process_launcher_.reset(); | 2106 child_process_launcher_.reset(); |
| 2114 channel_.reset(); | 2107 channel_.reset(); |
| 2115 while (!queued_messages_.empty()) { | 2108 while (!queued_messages_.empty()) { |
| 2116 delete queued_messages_.front(); | 2109 delete queued_messages_.front(); |
| 2117 queued_messages_.pop(); | 2110 queued_messages_.pop(); |
| 2118 } | 2111 } |
| 2112 UpdateProcessPriority(); | |
| 2113 DCHECK(!is_process_backgrounded_); | |
| 2119 | 2114 |
| 2120 within_process_died_observer_ = true; | 2115 within_process_died_observer_ = true; |
| 2121 NotificationService::current()->Notify( | 2116 NotificationService::current()->Notify( |
| 2122 NOTIFICATION_RENDERER_PROCESS_CLOSED, | 2117 NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| 2123 Source<RenderProcessHost>(this), | 2118 Source<RenderProcessHost>(this), |
| 2124 Details<RendererClosedDetails>(&details)); | 2119 Details<RendererClosedDetails>(&details)); |
| 2125 FOR_EACH_OBSERVER(RenderProcessHostObserver, | 2120 FOR_EACH_OBSERVER(RenderProcessHostObserver, |
| 2126 observers_, | 2121 observers_, |
| 2127 RenderProcessExited(this, status, exit_code)); | 2122 RenderProcessExited(this, status, exit_code)); |
| 2128 within_process_died_observer_ = false; | 2123 within_process_died_observer_ = false; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2231 | 2226 |
| 2232 mojo_application_host_->WillDestroySoon(); | 2227 mojo_application_host_->WillDestroySoon(); |
| 2233 | 2228 |
| 2234 Send(new ChildProcessMsg_Shutdown()); | 2229 Send(new ChildProcessMsg_Shutdown()); |
| 2235 } | 2230 } |
| 2236 | 2231 |
| 2237 void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) { | 2232 void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) { |
| 2238 SetSuddenTerminationAllowed(enabled); | 2233 SetSuddenTerminationAllowed(enabled); |
| 2239 } | 2234 } |
| 2240 | 2235 |
| 2241 void RenderProcessHostImpl::SetBackgrounded(bool backgrounded) { | 2236 void RenderProcessHostImpl::UpdateProcessPriority() { |
| 2242 TRACE_EVENT1("renderer_host", "RenderProcessHostImpl::SetBackgrounded", | 2237 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
|
gab
2015/07/08 18:50:56
const
| |
| 2243 "backgrounded", backgrounded); | 2238 bool process_exists = |
| 2244 // Note: we always set the backgrounded_ value. If the process is NULL | 2239 child_process_launcher_.get() && !child_process_launcher_->IsStarting(); |
| 2245 // (and hence hasn't been created yet), we will set the process priority | 2240 |
| 2246 // later when we create the process. | 2241 // We background a process as soon as it hosts no active audio streams and no |
| 2247 backgrounded_ = backgrounded; | 2242 // visible widgets -- the callers must call this function whenever we |
| 2248 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting()) | 2243 // transition in/out of those states. Processes are initially launched with |
| 2244 // foreground priority, so when the process doesn't exist. | |
| 2245 bool backgrounded = | |
|
gab
2015/07/08 18:50:56
s/backgrounded/should_background/ ?
| |
| 2246 process_exists && visible_widgets_ == 0 && | |
| 2247 !audio_renderer_host_->HasActiveAudio() && | |
| 2248 !command_line->HasSwitch(switches::kDisableRendererBackgrounding); | |
| 2249 | |
| 2250 if (is_process_backgrounded_ == backgrounded) | |
| 2249 return; | 2251 return; |
|
gab
2015/07/08 18:50:56
I would just keep this early return, I find it eas
ncarter (slow)
2015/07/08 19:07:19
Good point.
Though, it's important to actually se
| |
| 2250 | 2252 |
| 2251 // Don't background processes which have active audio streams. | 2253 TRACE_EVENT1("renderer_host", "RenderProcessHostImpl::UpdateProcessPriority", |
|
gab
2015/07/08 18:50:56
I think the trace should remain at the top (it's n
ncarter (slow)
2015/07/08 19:07:19
Because we're now computing |backgrounded| in the
| |
| 2252 if (backgrounded_ && audio_renderer_host_->HasActiveAudio()) | 2254 "backgrounded", backgrounded); |
| 2253 return; | 2255 is_process_backgrounded_ = backgrounded; |
| 2254 | 2256 |
| 2255 const base::CommandLine* command_line = | 2257 if (!process_exists) |
| 2256 base::CommandLine::ForCurrentProcess(); | 2258 return; // Nothing to background. |
| 2257 if (command_line->HasSwitch(switches::kDisableRendererBackgrounding)) | |
| 2258 return; | |
| 2259 | 2259 |
| 2260 #if defined(OS_WIN) | 2260 #if defined(OS_WIN) |
| 2261 // The cbstext.dll loads as a global GetMessage hook in the browser process | 2261 // The cbstext.dll loads as a global GetMessage hook in the browser process |
| 2262 // and intercepts/unintercepts the kernel32 API SetPriorityClass in a | 2262 // and intercepts/unintercepts the kernel32 API SetPriorityClass in a |
| 2263 // background thread. If the UI thread invokes this API just when it is | 2263 // background thread. If the UI thread invokes this API just when it is |
| 2264 // intercepted the stack is messed up on return from the interceptor | 2264 // intercepted the stack is messed up on return from the interceptor |
| 2265 // which causes random crashes in the browser process. Our hack for now | 2265 // which causes random crashes in the browser process. Our hack for now |
| 2266 // is to not invoke the SetPriorityClass API if the dll is loaded. | 2266 // is to not invoke the SetPriorityClass API if the dll is loaded. |
| 2267 if (GetModuleHandle(L"cbstext.dll")) | 2267 if (GetModuleHandle(L"cbstext.dll")) |
| 2268 return; | 2268 return; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2304 if (deleting_soon_) | 2304 if (deleting_soon_) |
| 2305 return; | 2305 return; |
| 2306 | 2306 |
| 2307 if (child_process_launcher_) { | 2307 if (child_process_launcher_) { |
| 2308 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 | 2308 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 |
| 2309 // is fixed. | 2309 // is fixed. |
| 2310 tracked_objects::ScopedTracker tracking_profile2( | 2310 tracked_objects::ScopedTracker tracking_profile2( |
| 2311 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2311 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 2312 "465841 RenderProcessHostImpl::OnProcessLaunched::Backgrounded")); | 2312 "465841 RenderProcessHostImpl::OnProcessLaunched::Backgrounded")); |
| 2313 DCHECK(child_process_launcher_->GetProcess().IsValid()); | 2313 DCHECK(child_process_launcher_->GetProcess().IsValid()); |
| 2314 SetBackgrounded(backgrounded_); | 2314 DCHECK(!is_process_backgrounded_); |
| 2315 UpdateProcessPriority(); | |
| 2315 } | 2316 } |
| 2316 | 2317 |
| 2317 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 | 2318 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 |
| 2318 // is fixed. | 2319 // is fixed. |
| 2319 tracked_objects::ScopedTracker tracking_profile3( | 2320 tracked_objects::ScopedTracker tracking_profile3( |
| 2320 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2321 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 2321 "465841 RenderProcessHostImpl::OnProcessLaunched::Notify")); | 2322 "465841 RenderProcessHostImpl::OnProcessLaunched::Notify")); |
| 2322 // NOTE: This needs to be before sending queued messages because | 2323 // NOTE: This needs to be before sending queued messages because |
| 2323 // ExtensionService uses this notification to initialize the renderer process | 2324 // ExtensionService uses this notification to initialize the renderer process |
| 2324 // with state that must be there before any JavaScript executes. | 2325 // with state that must be there before any JavaScript executes. |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2514 void RenderProcessHostImpl::GetAudioOutputControllers( | 2515 void RenderProcessHostImpl::GetAudioOutputControllers( |
| 2515 const GetAudioOutputControllersCallback& callback) const { | 2516 const GetAudioOutputControllersCallback& callback) const { |
| 2516 audio_renderer_host()->GetOutputControllers(callback); | 2517 audio_renderer_host()->GetOutputControllers(callback); |
| 2517 } | 2518 } |
| 2518 | 2519 |
| 2519 BluetoothDispatcherHost* RenderProcessHostImpl::GetBluetoothDispatcherHost() { | 2520 BluetoothDispatcherHost* RenderProcessHostImpl::GetBluetoothDispatcherHost() { |
| 2520 return bluetooth_dispatcher_host_.get(); | 2521 return bluetooth_dispatcher_host_.get(); |
| 2521 } | 2522 } |
| 2522 | 2523 |
| 2523 } // namespace content | 2524 } // namespace content |
| OLD | NEW |