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 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
488 StoragePartitionImpl* storage_partition_impl, | 488 StoragePartitionImpl* storage_partition_impl, |
489 bool is_for_guests_only) | 489 bool is_for_guests_only) |
490 : fast_shutdown_started_(false), | 490 : fast_shutdown_started_(false), |
491 deleting_soon_(false), | 491 deleting_soon_(false), |
492 #ifndef NDEBUG | 492 #ifndef NDEBUG |
493 is_self_deleted_(false), | 493 is_self_deleted_(false), |
494 #endif | 494 #endif |
495 pending_views_(0), | 495 pending_views_(0), |
496 mojo_application_host_(new MojoApplicationHost), | 496 mojo_application_host_(new MojoApplicationHost), |
497 visible_widgets_(0), | 497 visible_widgets_(0), |
498 backgrounded_(true), | 498 is_process_backgrounded_(false), |
499 is_initialized_(false), | 499 is_initialized_(false), |
500 id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), | 500 id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), |
501 browser_context_(browser_context), | 501 browser_context_(browser_context), |
502 storage_partition_impl_(storage_partition_impl), | 502 storage_partition_impl_(storage_partition_impl), |
503 sudden_termination_allowed_(true), | 503 sudden_termination_allowed_(true), |
504 ignore_input_events_(false), | 504 ignore_input_events_(false), |
505 is_for_guests_only_(is_for_guests_only), | 505 is_for_guests_only_(is_for_guests_only), |
506 gpu_observer_registered_(false), | 506 gpu_observer_registered_(false), |
507 delayed_cleanup_needed_(false), | 507 delayed_cleanup_needed_(false), |
508 within_process_died_observer_(false), | 508 within_process_died_observer_(false), |
(...skipping 17 matching lines...) Expand all Loading... | |
526 if (!GetBrowserContext()->IsOffTheRecord() && | 526 if (!GetBrowserContext()->IsOffTheRecord() && |
527 !base::CommandLine::ForCurrentProcess()->HasSwitch( | 527 !base::CommandLine::ForCurrentProcess()->HasSwitch( |
528 switches::kDisableGpuShaderDiskCache)) { | 528 switches::kDisableGpuShaderDiskCache)) { |
529 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 529 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
530 base::Bind(&CacheShaderInfo, GetID(), | 530 base::Bind(&CacheShaderInfo, GetID(), |
531 storage_partition_impl_->GetPath())); | 531 storage_partition_impl_->GetPath())); |
532 } | 532 } |
533 subscribe_uniform_enabled_ = | 533 subscribe_uniform_enabled_ = |
534 base::CommandLine::ForCurrentProcess()->HasSwitch( | 534 base::CommandLine::ForCurrentProcess()->HasSwitch( |
535 switches::kEnableSubscribeUniformExtension); | 535 switches::kEnableSubscribeUniformExtension); |
536 | |
537 // Note: When we create the RenderProcessHostImpl, it's technically | |
538 // backgrounded, because it has no visible listeners. But the process | |
539 // doesn't actually exist yet, so we'll Background it later, after | |
540 // creation. | |
541 } | 536 } |
542 | 537 |
543 // static | 538 // static |
544 void RenderProcessHostImpl::ShutDownInProcessRenderer() { | 539 void RenderProcessHostImpl::ShutDownInProcessRenderer() { |
545 DCHECK(g_run_renderer_in_process_); | 540 DCHECK(g_run_renderer_in_process_); |
546 | 541 |
547 switch (g_all_hosts.Pointer()->size()) { | 542 switch (g_all_hosts.Pointer()->size()) { |
548 case 0: | 543 case 0: |
549 return; | 544 return; |
550 case 1: { | 545 case 1: { |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1082 // In single process mode it is better if we don't suicide but just | 1077 // In single process mode it is better if we don't suicide but just |
1083 // crash. | 1078 // crash. |
1084 CHECK(false); | 1079 CHECK(false); |
1085 } | 1080 } |
1086 // We kill the renderer but don't include a NOTREACHED, because we want the | 1081 // We kill the renderer but don't include a NOTREACHED, because we want the |
1087 // browser to try to survive when it gets illegal messages from the renderer. | 1082 // browser to try to survive when it gets illegal messages from the renderer. |
1088 Shutdown(RESULT_CODE_KILLED_BAD_MESSAGE, false); | 1083 Shutdown(RESULT_CODE_KILLED_BAD_MESSAGE, false); |
1089 } | 1084 } |
1090 | 1085 |
1091 void RenderProcessHostImpl::WidgetRestored() { | 1086 void RenderProcessHostImpl::WidgetRestored() { |
1092 // Verify we were properly backgrounded. | |
1093 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0)); | |
1094 visible_widgets_++; | 1087 visible_widgets_++; |
1095 SetBackgrounded(false); | 1088 UpdateProcessPriority(); |
1089 DCHECK(!is_process_backgrounded_); | |
1096 } | 1090 } |
1097 | 1091 |
1098 void RenderProcessHostImpl::WidgetHidden() { | 1092 void RenderProcessHostImpl::WidgetHidden() { |
1099 // On startup, the browser will call Hide | 1093 // On startup, the browser will call Hide. We ignore this call. |
1100 if (backgrounded_) | 1094 if (visible_widgets_ == 0) |
1101 return; | 1095 return; |
1102 | 1096 |
1103 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0)); | 1097 --visible_widgets_; |
1104 visible_widgets_--; | |
1105 DCHECK_GE(visible_widgets_, 0); | |
1106 if (visible_widgets_ == 0) { | 1098 if (visible_widgets_ == 0) { |
1107 DCHECK(!backgrounded_); | 1099 DCHECK(!is_process_backgrounded_); |
1108 SetBackgrounded(true); | 1100 UpdateProcessPriority(); |
1109 } | 1101 } |
1110 } | 1102 } |
1111 | 1103 |
1112 int RenderProcessHostImpl::VisibleWidgetCount() const { | 1104 int RenderProcessHostImpl::VisibleWidgetCount() const { |
1113 return visible_widgets_; | 1105 return visible_widgets_; |
1114 } | 1106 } |
1115 | 1107 |
1108 void RenderProcessHostImpl::AudioStateChanged() { | |
1109 UpdateProcessPriority(); | |
1110 } | |
1111 | |
1116 bool RenderProcessHostImpl::IsForGuestsOnly() const { | 1112 bool RenderProcessHostImpl::IsForGuestsOnly() const { |
1117 return is_for_guests_only_; | 1113 return is_for_guests_only_; |
1118 } | 1114 } |
1119 | 1115 |
1120 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { | 1116 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { |
1121 return storage_partition_impl_; | 1117 return storage_partition_impl_; |
1122 } | 1118 } |
1123 | 1119 |
1124 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { | 1120 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { |
1125 if (IsPropertyTreeVerificationEnabled()) | 1121 if (IsPropertyTreeVerificationEnabled()) |
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2128 | 2124 |
2129 RendererClosedDetails details(status, exit_code); | 2125 RendererClosedDetails details(status, exit_code); |
2130 mojo_application_host_->WillDestroySoon(); | 2126 mojo_application_host_->WillDestroySoon(); |
2131 | 2127 |
2132 child_process_launcher_.reset(); | 2128 child_process_launcher_.reset(); |
2133 channel_.reset(); | 2129 channel_.reset(); |
2134 while (!queued_messages_.empty()) { | 2130 while (!queued_messages_.empty()) { |
2135 delete queued_messages_.front(); | 2131 delete queued_messages_.front(); |
2136 queued_messages_.pop(); | 2132 queued_messages_.pop(); |
2137 } | 2133 } |
2134 UpdateProcessPriority(); | |
2135 DCHECK(!is_process_backgrounded_); | |
2138 | 2136 |
2139 within_process_died_observer_ = true; | 2137 within_process_died_observer_ = true; |
2140 NotificationService::current()->Notify( | 2138 NotificationService::current()->Notify( |
2141 NOTIFICATION_RENDERER_PROCESS_CLOSED, | 2139 NOTIFICATION_RENDERER_PROCESS_CLOSED, |
2142 Source<RenderProcessHost>(this), | 2140 Source<RenderProcessHost>(this), |
2143 Details<RendererClosedDetails>(&details)); | 2141 Details<RendererClosedDetails>(&details)); |
2144 FOR_EACH_OBSERVER(RenderProcessHostObserver, | 2142 FOR_EACH_OBSERVER(RenderProcessHostObserver, |
2145 observers_, | 2143 observers_, |
2146 RenderProcessExited(this, status, exit_code)); | 2144 RenderProcessExited(this, status, exit_code)); |
2147 within_process_died_observer_ = false; | 2145 within_process_died_observer_ = false; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2245 | 2243 |
2246 mojo_application_host_->WillDestroySoon(); | 2244 mojo_application_host_->WillDestroySoon(); |
2247 | 2245 |
2248 Send(new ChildProcessMsg_Shutdown()); | 2246 Send(new ChildProcessMsg_Shutdown()); |
2249 } | 2247 } |
2250 | 2248 |
2251 void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) { | 2249 void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) { |
2252 SetSuddenTerminationAllowed(enabled); | 2250 SetSuddenTerminationAllowed(enabled); |
2253 } | 2251 } |
2254 | 2252 |
2255 void RenderProcessHostImpl::SetBackgrounded(bool backgrounded) { | 2253 void RenderProcessHostImpl::UpdateProcessPriority() { |
2256 TRACE_EVENT1("renderer_host", "RenderProcessHostImpl::SetBackgrounded", | 2254 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting()) { |
2257 "backgrounded", backgrounded); | 2255 is_process_backgrounded_ = false; |
2258 // Note: we always set the backgrounded_ value. If the process is NULL | 2256 return; |
2259 // (and hence hasn't been created yet), we will set the process priority | 2257 } |
2260 // later when we create the process. | 2258 |
2261 backgrounded_ = backgrounded; | 2259 // We background a process as soon as it hosts no active audio streams and no |
2262 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting()) | 2260 // visible widgets -- the callers must call this function whenever we |
2261 // transition in/out of thoses states. Processes are initially launched with | |
Avi (use Gerrit)
2015/08/19 00:30:29
"those states"
sebsg
2015/08/19 15:22:21
Done.
| |
2262 // foreground priority, so when the process doesn't exist. | |
Avi (use Gerrit)
2015/08/19 00:30:29
"so when the process doesn't exist..." what? Compl
sebsg
2015/08/19 15:22:21
Thanks for noticing that, the comment was made whe
| |
2263 const bool should_background = | |
2264 visible_widgets_ == 0 && !audio_renderer_host_->HasActiveAudio() && | |
2265 !base::CommandLine::ForCurrentProcess()->HasSwitch( | |
2266 switches::kDisableRendererBackgrounding); | |
2267 | |
2268 if (is_process_backgrounded_ == should_background) | |
2263 return; | 2269 return; |
2264 | 2270 |
2265 // Don't background processes which have active audio streams. | 2271 TRACE_EVENT1("renderer_host", "RenderProcessHostImpl::UpdateProcessPriority", |
2266 if (backgrounded_ && audio_renderer_host_->HasActiveAudio()) | 2272 "should_background", should_background); |
2267 return; | 2273 is_process_backgrounded_ = should_background; |
2268 | |
2269 const base::CommandLine* command_line = | |
2270 base::CommandLine::ForCurrentProcess(); | |
2271 if (command_line->HasSwitch(switches::kDisableRendererBackgrounding)) | |
2272 return; | |
2273 | 2274 |
2274 #if defined(OS_WIN) | 2275 #if defined(OS_WIN) |
2275 // The cbstext.dll loads as a global GetMessage hook in the browser process | 2276 // The cbstext.dll loads as a global GetMessage hook in the browser process |
2276 // and intercepts/unintercepts the kernel32 API SetPriorityClass in a | 2277 // and intercepts/unintercepts the kernel32 API SetPriorityClass in a |
2277 // background thread. If the UI thread invokes this API just when it is | 2278 // background thread. If the UI thread invokes this API just when it is |
2278 // intercepted the stack is messed up on return from the interceptor | 2279 // intercepted the stack is messed up on return from the interceptor |
2279 // which causes random crashes in the browser process. Our hack for now | 2280 // which causes random crashes in the browser process. Our hack for now |
2280 // is to not invoke the SetPriorityClass API if the dll is loaded. | 2281 // is to not invoke the SetPriorityClass API if the dll is loaded. |
2281 if (GetModuleHandle(L"cbstext.dll")) | 2282 if (GetModuleHandle(L"cbstext.dll")) |
2282 return; | 2283 return; |
2283 #endif // OS_WIN | 2284 #endif // OS_WIN |
2284 | 2285 |
2285 #if defined(OS_WIN) || defined(OS_MACOSX) | 2286 #if defined(OS_WIN) || defined(OS_MACOSX) |
2286 // Same as below, but bound to an experiment (http://crbug.com/458594 on | 2287 // Same as below, but bound to an experiment (http://crbug.com/458594 on |
2287 // Windows, http://crbug.com/398103 on the Mac). Enabled by default in the | 2288 // Windows, http://crbug.com/398103 on the Mac). Enabled by default in the |
2288 // absence of field trials to get coverage on the perf waterfall. | 2289 // absence of field trials to get coverage on the perf waterfall. |
2289 base::FieldTrial* trial = | 2290 base::FieldTrial* trial = |
2290 base::FieldTrialList::Find("BackgroundRendererProcesses"); | 2291 base::FieldTrialList::Find("BackgroundRendererProcesses"); |
2291 if (!trial || !base::StartsWith(trial->group_name(), "Disallow", | 2292 if (!trial || !base::StartsWith(trial->group_name(), "Disallow", |
2292 base::CompareCase::SENSITIVE)) { | 2293 base::CompareCase::SENSITIVE)) { |
2293 child_process_launcher_->SetProcessBackgrounded(backgrounded); | 2294 child_process_launcher_->SetProcessBackgrounded(should_background); |
2294 } | 2295 } |
2295 #else | 2296 #else |
2296 // Control the background state from the browser process, otherwise the task | 2297 // Control the background state from the browser process, otherwise the task |
2297 // telling the renderer to "unbackground" itself may be preempted by other | 2298 // telling the renderer to "unbackground" itself may be preempted by other |
2298 // tasks executing at lowered priority ahead of it or simply by not being | 2299 // tasks executing at lowered priority ahead of it or simply by not being |
2299 // swiftly scheduled by the OS per the low process priority | 2300 // swiftly scheduled by the OS per the low process priority |
2300 // (http://crbug.com/398103). | 2301 // (http://crbug.com/398103). |
2301 child_process_launcher_->SetProcessBackgrounded(backgrounded); | 2302 child_process_launcher_->SetProcessBackgrounded(should_background); |
2302 #endif // OS_WIN | 2303 #endif // OS_WIN |
2303 | 2304 |
2304 // Notify the child process of background state. | 2305 // Notify the child process of background state. |
2305 Send(new ChildProcessMsg_SetProcessBackgrounded(backgrounded)); | 2306 Send(new ChildProcessMsg_SetProcessBackgrounded(should_background)); |
2306 } | 2307 } |
2307 | 2308 |
2308 void RenderProcessHostImpl::OnProcessLaunched() { | 2309 void RenderProcessHostImpl::OnProcessLaunched() { |
2309 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 | 2310 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 |
2310 // is fixed. | 2311 // is fixed. |
2311 tracked_objects::ScopedTracker tracking_profile1( | 2312 tracked_objects::ScopedTracker tracking_profile1( |
2312 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2313 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
2313 "465841 RenderProcessHostImpl::OnProcessLaunched::Start")); | 2314 "465841 RenderProcessHostImpl::OnProcessLaunched::Start")); |
2314 // No point doing anything, since this object will be destructed soon. We | 2315 // No point doing anything, since this object will be destructed soon. We |
2315 // especially don't want to send the RENDERER_PROCESS_CREATED notification, | 2316 // especially don't want to send the RENDERER_PROCESS_CREATED notification, |
2316 // since some clients might expect a RENDERER_PROCESS_TERMINATED afterwards to | 2317 // since some clients might expect a RENDERER_PROCESS_TERMINATED afterwards to |
2317 // properly cleanup. | 2318 // properly cleanup. |
2318 if (deleting_soon_) | 2319 if (deleting_soon_) |
2319 return; | 2320 return; |
2320 | 2321 |
2321 if (child_process_launcher_) { | 2322 if (child_process_launcher_) { |
2322 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 | 2323 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 |
2323 // is fixed. | 2324 // is fixed. |
2324 tracked_objects::ScopedTracker tracking_profile2( | 2325 tracked_objects::ScopedTracker tracking_profile2( |
2325 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2326 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
2326 "465841 RenderProcessHostImpl::OnProcessLaunched::Backgrounded")); | 2327 "465841 RenderProcessHostImpl::OnProcessLaunched::Backgrounded")); |
2327 DCHECK(child_process_launcher_->GetProcess().IsValid()); | 2328 DCHECK(child_process_launcher_->GetProcess().IsValid()); |
2328 SetBackgrounded(backgrounded_); | 2329 DCHECK(!is_process_backgrounded_); |
2330 UpdateProcessPriority(); | |
2329 } | 2331 } |
2330 | 2332 |
2331 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 | 2333 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 |
2332 // is fixed. | 2334 // is fixed. |
2333 tracked_objects::ScopedTracker tracking_profile3( | 2335 tracked_objects::ScopedTracker tracking_profile3( |
2334 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2336 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
2335 "465841 RenderProcessHostImpl::OnProcessLaunched::Notify")); | 2337 "465841 RenderProcessHostImpl::OnProcessLaunched::Notify")); |
2336 // NOTE: This needs to be before sending queued messages because | 2338 // NOTE: This needs to be before sending queued messages because |
2337 // ExtensionService uses this notification to initialize the renderer process | 2339 // ExtensionService uses this notification to initialize the renderer process |
2338 // with state that must be there before any JavaScript executes. | 2340 // with state that must be there before any JavaScript executes. |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2528 void RenderProcessHostImpl::GetAudioOutputControllers( | 2530 void RenderProcessHostImpl::GetAudioOutputControllers( |
2529 const GetAudioOutputControllersCallback& callback) const { | 2531 const GetAudioOutputControllersCallback& callback) const { |
2530 audio_renderer_host()->GetOutputControllers(callback); | 2532 audio_renderer_host()->GetOutputControllers(callback); |
2531 } | 2533 } |
2532 | 2534 |
2533 BluetoothDispatcherHost* RenderProcessHostImpl::GetBluetoothDispatcherHost() { | 2535 BluetoothDispatcherHost* RenderProcessHostImpl::GetBluetoothDispatcherHost() { |
2534 return bluetooth_dispatcher_host_.get(); | 2536 return bluetooth_dispatcher_host_.get(); |
2535 } | 2537 } |
2536 | 2538 |
2537 } // namespace content | 2539 } // namespace content |
OLD | NEW |