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 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1061 // In single process mode it is better if we don't suicide but just | 1056 // In single process mode it is better if we don't suicide but just |
1062 // crash. | 1057 // crash. |
1063 CHECK(false); | 1058 CHECK(false); |
1064 } | 1059 } |
1065 // We kill the renderer but don't include a NOTREACHED, because we want the | 1060 // We kill the renderer but don't include a NOTREACHED, because we want the |
1066 // browser to try to survive when it gets illegal messages from the renderer. | 1061 // browser to try to survive when it gets illegal messages from the renderer. |
1067 Shutdown(RESULT_CODE_KILLED_BAD_MESSAGE, false); | 1062 Shutdown(RESULT_CODE_KILLED_BAD_MESSAGE, false); |
1068 } | 1063 } |
1069 | 1064 |
1070 void RenderProcessHostImpl::WidgetRestored() { | 1065 void RenderProcessHostImpl::WidgetRestored() { |
1071 // Verify we were properly backgrounded. | 1066 // Verify we were properly backgrounded. |
gab
2015/08/04 19:40:24
This comment is now obsolete.
sebsg
2015/08/06 21:11:47
Done.
| |
1072 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0)); | |
1073 visible_widgets_++; | 1067 visible_widgets_++; |
1074 SetBackgrounded(false); | 1068 UpdateProcessPriority(); |
1069 DCHECK(!is_process_backgrounded_); | |
1075 } | 1070 } |
1076 | 1071 |
1077 void RenderProcessHostImpl::WidgetHidden() { | 1072 void RenderProcessHostImpl::WidgetHidden() { |
1078 // On startup, the browser will call Hide | 1073 // On startup, the browser will call Hide. We ignore these calls. |
gab
2015/08/04 19:40:24
s/these calls/this call/
sebsg
2015/08/06 21:11:47
Done.
| |
1079 if (backgrounded_) | 1074 if (visible_widgets_ == 0) |
1080 return; | 1075 return; |
1081 | 1076 |
1082 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0)); | 1077 DCHECK_GT(visible_widgets_, 0); |
miu
2015/08/04 20:30:20
Might as well remove this DCHECK since it can neve
sebsg
2015/08/06 21:11:47
Done.
| |
1083 visible_widgets_--; | 1078 if (--visible_widgets_ == 0) { |
gab
2015/08/04 19:40:24
In Chromium we typically prefer not having inline
sebsg
2015/08/06 21:11:47
Done.
| |
1084 DCHECK_GE(visible_widgets_, 0); | 1079 DCHECK(!is_process_backgrounded_); |
1085 if (visible_widgets_ == 0) { | 1080 UpdateProcessPriority(); |
1086 DCHECK(!backgrounded_); | |
1087 SetBackgrounded(true); | |
1088 } | 1081 } |
1089 } | 1082 } |
1090 | 1083 |
1091 int RenderProcessHostImpl::VisibleWidgetCount() const { | 1084 int RenderProcessHostImpl::VisibleWidgetCount() const { |
1092 return visible_widgets_; | 1085 return visible_widgets_; |
1093 } | 1086 } |
1094 | 1087 |
1088 void RenderProcessHostImpl::AudioStateChanged() { | |
1089 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
gab
2015/08/04 19:40:24
As Nick said, this class is not thread safe (i.e.
sebsg
2015/08/06 21:11:47
Done.
| |
1090 UpdateProcessPriority(); | |
1091 } | |
1092 | |
1095 bool RenderProcessHostImpl::IsForGuestsOnly() const { | 1093 bool RenderProcessHostImpl::IsForGuestsOnly() const { |
1096 return is_for_guests_only_; | 1094 return is_for_guests_only_; |
1097 } | 1095 } |
1098 | 1096 |
1099 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { | 1097 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { |
1100 return storage_partition_impl_; | 1098 return storage_partition_impl_; |
1101 } | 1099 } |
1102 | 1100 |
1103 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { | 1101 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { |
1104 if (IsPropertyTreeVerificationEnabled()) | 1102 if (IsPropertyTreeVerificationEnabled()) |
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2107 | 2105 |
2108 RendererClosedDetails details(status, exit_code); | 2106 RendererClosedDetails details(status, exit_code); |
2109 mojo_application_host_->WillDestroySoon(); | 2107 mojo_application_host_->WillDestroySoon(); |
2110 | 2108 |
2111 child_process_launcher_.reset(); | 2109 child_process_launcher_.reset(); |
2112 channel_.reset(); | 2110 channel_.reset(); |
2113 while (!queued_messages_.empty()) { | 2111 while (!queued_messages_.empty()) { |
2114 delete queued_messages_.front(); | 2112 delete queued_messages_.front(); |
2115 queued_messages_.pop(); | 2113 queued_messages_.pop(); |
2116 } | 2114 } |
2115 UpdateProcessPriority(); | |
2116 DCHECK(!is_process_backgrounded_); | |
2117 | 2117 |
2118 within_process_died_observer_ = true; | 2118 within_process_died_observer_ = true; |
2119 NotificationService::current()->Notify( | 2119 NotificationService::current()->Notify( |
2120 NOTIFICATION_RENDERER_PROCESS_CLOSED, | 2120 NOTIFICATION_RENDERER_PROCESS_CLOSED, |
2121 Source<RenderProcessHost>(this), | 2121 Source<RenderProcessHost>(this), |
2122 Details<RendererClosedDetails>(&details)); | 2122 Details<RendererClosedDetails>(&details)); |
2123 FOR_EACH_OBSERVER(RenderProcessHostObserver, | 2123 FOR_EACH_OBSERVER(RenderProcessHostObserver, |
2124 observers_, | 2124 observers_, |
2125 RenderProcessExited(this, status, exit_code)); | 2125 RenderProcessExited(this, status, exit_code)); |
2126 within_process_died_observer_ = false; | 2126 within_process_died_observer_ = false; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2229 | 2229 |
2230 mojo_application_host_->WillDestroySoon(); | 2230 mojo_application_host_->WillDestroySoon(); |
2231 | 2231 |
2232 Send(new ChildProcessMsg_Shutdown()); | 2232 Send(new ChildProcessMsg_Shutdown()); |
2233 } | 2233 } |
2234 | 2234 |
2235 void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) { | 2235 void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) { |
2236 SetSuddenTerminationAllowed(enabled); | 2236 SetSuddenTerminationAllowed(enabled); |
2237 } | 2237 } |
2238 | 2238 |
2239 void RenderProcessHostImpl::SetBackgrounded(bool backgrounded) { | 2239 void RenderProcessHostImpl::UpdateProcessPriority() { |
2240 TRACE_EVENT1("renderer_host", "RenderProcessHostImpl::SetBackgrounded", | 2240 const base::CommandLine* command_line = |
2241 "backgrounded", backgrounded); | 2241 base::CommandLine::ForCurrentProcess(); |
gab
2015/08/04 19:40:24
inline this below since you only need it once
sebsg
2015/08/06 21:11:47
Done.
| |
2242 // Note: we always set the backgrounded_ value. If the process is NULL | 2242 bool process_exists = |
gab
2015/08/04 19:40:24
const
sebsg
2015/08/06 21:11:47
Done.
| |
2243 // (and hence hasn't been created yet), we will set the process priority | 2243 child_process_launcher_.get() && !child_process_launcher_->IsStarting(); |
2244 // later when we create the process. | 2244 |
2245 backgrounded_ = backgrounded; | 2245 // We background a process as soon as it hosts no active audio streams and no |
2246 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting()) | 2246 // visible widgets -- the callers must call this function whenever we |
2247 // transition in/out of thoses states. Processes are initially launched with | |
2248 // foreground priority, so when the process doesn't exist. | |
2249 bool should_background = | |
gab
2015/08/04 19:40:24
const
sebsg
2015/08/06 21:11:47
Done.
| |
2250 process_exists && visible_widgets_ == 0 && | |
2251 !audio_renderer_host_->HasActiveAudio() && | |
2252 !command_line->HasSwitch(switches::kDisableRendererBackgrounding); | |
2253 | |
2254 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting()) { | |
miu
2015/08/04 20:30:20
nit: This if-statement should be at the top of the
sebsg
2015/08/06 21:11:47
Done.
| |
2255 is_process_backgrounded_ = false; | |
2256 return; | |
2257 } | |
gab
2015/08/04 19:40:24
This is essentially:
if (!process_exists) {
is_
ncarter (slow)
2015/08/04 22:23:23
The only choice here is whether you want the TRACE
gab
2015/08/06 16:35:02
Hmm, won't the TRACE_EVENT code below be hit in th
ncarter (slow)
2015/08/06 18:16:39
Yes, it will. Sorry my comment wasn't clearer. I w
sebsg
2015/08/06 21:11:47
Done.
sebsg
2015/08/06 21:11:47
Done.
sebsg
2015/08/06 21:11:47
Done.
sebsg
2015/08/06 21:11:47
Done.
| |
2258 | |
2259 if (is_process_backgrounded_ == should_background) | |
2247 return; | 2260 return; |
2248 | 2261 |
2249 // Don't background processes which have active audio streams. | 2262 TRACE_EVENT1("renderer_host", "RenderProcessHostImpl::UpdateProcessPriority", |
2250 if (backgrounded_ && audio_renderer_host_->HasActiveAudio()) | 2263 "should_background", should_background); |
2251 return; | 2264 is_process_backgrounded_ = should_background; |
2252 | 2265 |
2253 const base::CommandLine* command_line = | 2266 if (!process_exists) |
2254 base::CommandLine::ForCurrentProcess(); | 2267 return; // Nothing to background. |
2255 if (command_line->HasSwitch(switches::kDisableRendererBackgrounding)) | |
2256 return; | |
2257 | 2268 |
2258 #if defined(OS_WIN) | 2269 #if defined(OS_WIN) |
2259 // The cbstext.dll loads as a global GetMessage hook in the browser process | 2270 // The cbstext.dll loads as a global GetMessage hook in the browser process |
2260 // and intercepts/unintercepts the kernel32 API SetPriorityClass in a | 2271 // and intercepts/unintercepts the kernel32 API SetPriorityClass in a |
2261 // background thread. If the UI thread invokes this API just when it is | 2272 // background thread. If the UI thread invokes this API just when it is |
2262 // intercepted the stack is messed up on return from the interceptor | 2273 // intercepted the stack is messed up on return from the interceptor |
2263 // which causes random crashes in the browser process. Our hack for now | 2274 // which causes random crashes in the browser process. Our hack for now |
2264 // is to not invoke the SetPriorityClass API if the dll is loaded. | 2275 // is to not invoke the SetPriorityClass API if the dll is loaded. |
2265 if (GetModuleHandle(L"cbstext.dll")) | 2276 if (GetModuleHandle(L"cbstext.dll")) |
2266 return; | 2277 return; |
2267 #endif // OS_WIN | 2278 #endif // OS_WIN |
2268 | 2279 |
2269 #if defined(OS_WIN) || defined(OS_MACOSX) | 2280 #if defined(OS_WIN) || defined(OS_MACOSX) |
2270 // Same as below, but bound to an experiment (http://crbug.com/458594 on | 2281 // Same as below, but bound to an experiment (http://crbug.com/458594 on |
2271 // Windows, http://crbug.com/398103 on the Mac). Enabled by default in the | 2282 // Windows, http://crbug.com/398103 on the Mac). Enabled by default in the |
2272 // absence of field trials to get coverage on the perf waterfall. | 2283 // absence of field trials to get coverage on the perf waterfall. |
2273 base::FieldTrial* trial = | 2284 base::FieldTrial* trial = |
2274 base::FieldTrialList::Find("BackgroundRendererProcesses"); | 2285 base::FieldTrialList::Find("BackgroundRendererProcesses"); |
2275 if (!trial || !base::StartsWith(trial->group_name(), "Disallow", | 2286 if (!trial || !base::StartsWith(trial->group_name(), "Disallow", |
2276 base::CompareCase::SENSITIVE)) { | 2287 base::CompareCase::SENSITIVE)) { |
2277 child_process_launcher_->SetProcessBackgrounded(backgrounded); | 2288 child_process_launcher_->SetProcessBackgrounded(should_background); |
2278 } | 2289 } |
2279 #else | 2290 #else |
2280 // Control the background state from the browser process, otherwise the task | 2291 // Control the background state from the browser process, otherwise the task |
2281 // telling the renderer to "unbackground" itself may be preempted by other | 2292 // telling the renderer to "unbackground" itself may be preempted by other |
2282 // tasks executing at lowered priority ahead of it or simply by not being | 2293 // tasks executing at lowered priority ahead of it or simply by not being |
2283 // swiftly scheduled by the OS per the low process priority | 2294 // swiftly scheduled by the OS per the low process priority |
2284 // (http://crbug.com/398103). | 2295 // (http://crbug.com/398103). |
2285 child_process_launcher_->SetProcessBackgrounded(backgrounded); | 2296 child_process_launcher_->SetProcessBackgrounded(backgrounded); |
2286 #endif // OS_WIN | 2297 #endif // OS_WIN |
2287 | 2298 |
2288 // Notify the child process of background state. | 2299 // Notify the child process of background state. |
2289 Send(new ChildProcessMsg_SetProcessBackgrounded(backgrounded)); | 2300 Send(new ChildProcessMsg_SetProcessBackgrounded(should_background)); |
2290 } | 2301 } |
2291 | 2302 |
2292 void RenderProcessHostImpl::OnProcessLaunched() { | 2303 void RenderProcessHostImpl::OnProcessLaunched() { |
2293 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 | 2304 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 |
2294 // is fixed. | 2305 // is fixed. |
2295 tracked_objects::ScopedTracker tracking_profile1( | 2306 tracked_objects::ScopedTracker tracking_profile1( |
2296 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2307 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
2297 "465841 RenderProcessHostImpl::OnProcessLaunched::Start")); | 2308 "465841 RenderProcessHostImpl::OnProcessLaunched::Start")); |
2298 // No point doing anything, since this object will be destructed soon. We | 2309 // No point doing anything, since this object will be destructed soon. We |
2299 // especially don't want to send the RENDERER_PROCESS_CREATED notification, | 2310 // especially don't want to send the RENDERER_PROCESS_CREATED notification, |
2300 // since some clients might expect a RENDERER_PROCESS_TERMINATED afterwards to | 2311 // since some clients might expect a RENDERER_PROCESS_TERMINATED afterwards to |
2301 // properly cleanup. | 2312 // properly cleanup. |
2302 if (deleting_soon_) | 2313 if (deleting_soon_) |
2303 return; | 2314 return; |
2304 | 2315 |
2305 if (child_process_launcher_) { | 2316 if (child_process_launcher_) { |
2306 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 | 2317 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 |
2307 // is fixed. | 2318 // is fixed. |
2308 tracked_objects::ScopedTracker tracking_profile2( | 2319 tracked_objects::ScopedTracker tracking_profile2( |
2309 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2320 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
2310 "465841 RenderProcessHostImpl::OnProcessLaunched::Backgrounded")); | 2321 "465841 RenderProcessHostImpl::OnProcessLaunched::Backgrounded")); |
2311 DCHECK(child_process_launcher_->GetProcess().IsValid()); | 2322 DCHECK(child_process_launcher_->GetProcess().IsValid()); |
2312 SetBackgrounded(backgrounded_); | 2323 DCHECK(!is_process_backgrounded_); |
2324 UpdateProcessPriority(); | |
2313 } | 2325 } |
2314 | 2326 |
2315 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 | 2327 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 |
2316 // is fixed. | 2328 // is fixed. |
2317 tracked_objects::ScopedTracker tracking_profile3( | 2329 tracked_objects::ScopedTracker tracking_profile3( |
2318 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2330 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
2319 "465841 RenderProcessHostImpl::OnProcessLaunched::Notify")); | 2331 "465841 RenderProcessHostImpl::OnProcessLaunched::Notify")); |
2320 // NOTE: This needs to be before sending queued messages because | 2332 // NOTE: This needs to be before sending queued messages because |
2321 // ExtensionService uses this notification to initialize the renderer process | 2333 // ExtensionService uses this notification to initialize the renderer process |
2322 // with state that must be there before any JavaScript executes. | 2334 // with state that must be there before any JavaScript executes. |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2512 void RenderProcessHostImpl::GetAudioOutputControllers( | 2524 void RenderProcessHostImpl::GetAudioOutputControllers( |
2513 const GetAudioOutputControllersCallback& callback) const { | 2525 const GetAudioOutputControllersCallback& callback) const { |
2514 audio_renderer_host()->GetOutputControllers(callback); | 2526 audio_renderer_host()->GetOutputControllers(callback); |
2515 } | 2527 } |
2516 | 2528 |
2517 BluetoothDispatcherHost* RenderProcessHostImpl::GetBluetoothDispatcherHost() { | 2529 BluetoothDispatcherHost* RenderProcessHostImpl::GetBluetoothDispatcherHost() { |
2518 return bluetooth_dispatcher_host_.get(); | 2530 return bluetooth_dispatcher_host_.get(); |
2519 } | 2531 } |
2520 | 2532 |
2521 } // namespace content | 2533 } // namespace content |
OLD | NEW |