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 |