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 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 media::BrowserCdm* RenderProcessHostImpl::GetBrowserCdm(int render_frame_id, | 1035 media::BrowserCdm* RenderProcessHostImpl::GetBrowserCdm(int render_frame_id, |
1041 int cdm_id) const { | 1036 int cdm_id) const { |
1042 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1037 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1043 BrowserCdmManager* manager = BrowserCdmManager::FromProcess(GetID()); | 1038 BrowserCdmManager* manager = BrowserCdmManager::FromProcess(GetID()); |
1044 if (!manager) | 1039 if (!manager) |
1045 return nullptr; | 1040 return nullptr; |
1046 return manager->GetCdm(render_frame_id, cdm_id); | 1041 return manager->GetCdm(render_frame_id, cdm_id); |
1047 } | 1042 } |
1048 #endif | 1043 #endif |
1049 | 1044 |
| 1045 #if defined(OS_MACOSX) |
| 1046 mach_port_t RenderProcessHostImpl::GetMachTaskPortForTesting() const { |
| 1047 content::MachBroker* broker = content::MachBroker::GetInstance(); |
| 1048 return broker->TaskForPid(GetHandle()); |
| 1049 } |
| 1050 #endif |
| 1051 |
1050 void RenderProcessHostImpl::AddRoute( | 1052 void RenderProcessHostImpl::AddRoute( |
1051 int32 routing_id, | 1053 int32 routing_id, |
1052 IPC::Listener* listener) { | 1054 IPC::Listener* listener) { |
1053 CHECK(!listeners_.Lookup(routing_id)) | 1055 CHECK(!listeners_.Lookup(routing_id)) |
1054 << "Found Routing ID Conflict: " << routing_id; | 1056 << "Found Routing ID Conflict: " << routing_id; |
1055 listeners_.AddWithID(listener, routing_id); | 1057 listeners_.AddWithID(listener, routing_id); |
1056 } | 1058 } |
1057 | 1059 |
1058 void RenderProcessHostImpl::RemoveRoute(int32 routing_id) { | 1060 void RenderProcessHostImpl::RemoveRoute(int32 routing_id) { |
1059 DCHECK(listeners_.Lookup(routing_id) != NULL); | 1061 DCHECK(listeners_.Lookup(routing_id) != NULL); |
(...skipping 22 matching lines...) Expand all Loading... |
1082 // In single process mode it is better if we don't suicide but just | 1084 // In single process mode it is better if we don't suicide but just |
1083 // crash. | 1085 // crash. |
1084 CHECK(false); | 1086 CHECK(false); |
1085 } | 1087 } |
1086 // We kill the renderer but don't include a NOTREACHED, because we want the | 1088 // 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. | 1089 // browser to try to survive when it gets illegal messages from the renderer. |
1088 Shutdown(RESULT_CODE_KILLED_BAD_MESSAGE, false); | 1090 Shutdown(RESULT_CODE_KILLED_BAD_MESSAGE, false); |
1089 } | 1091 } |
1090 | 1092 |
1091 void RenderProcessHostImpl::WidgetRestored() { | 1093 void RenderProcessHostImpl::WidgetRestored() { |
1092 // Verify we were properly backgrounded. | |
1093 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0)); | |
1094 visible_widgets_++; | 1094 visible_widgets_++; |
1095 SetBackgrounded(false); | 1095 UpdateProcessPriority(); |
| 1096 DCHECK(!is_process_backgrounded_); |
1096 } | 1097 } |
1097 | 1098 |
1098 void RenderProcessHostImpl::WidgetHidden() { | 1099 void RenderProcessHostImpl::WidgetHidden() { |
1099 // On startup, the browser will call Hide | 1100 // On startup, the browser will call Hide. We ignore this call. |
1100 if (backgrounded_) | 1101 if (visible_widgets_ == 0) |
1101 return; | 1102 return; |
1102 | 1103 |
1103 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0)); | 1104 --visible_widgets_; |
1104 visible_widgets_--; | |
1105 DCHECK_GE(visible_widgets_, 0); | |
1106 if (visible_widgets_ == 0) { | 1105 if (visible_widgets_ == 0) { |
1107 DCHECK(!backgrounded_); | 1106 DCHECK(!is_process_backgrounded_); |
1108 SetBackgrounded(true); | 1107 UpdateProcessPriority(); |
1109 } | 1108 } |
1110 } | 1109 } |
1111 | 1110 |
1112 int RenderProcessHostImpl::VisibleWidgetCount() const { | 1111 int RenderProcessHostImpl::VisibleWidgetCount() const { |
1113 return visible_widgets_; | 1112 return visible_widgets_; |
1114 } | 1113 } |
1115 | 1114 |
| 1115 void RenderProcessHostImpl::AudioStateChanged() { |
| 1116 UpdateProcessPriority(); |
| 1117 } |
| 1118 |
1116 bool RenderProcessHostImpl::IsForGuestsOnly() const { | 1119 bool RenderProcessHostImpl::IsForGuestsOnly() const { |
1117 return is_for_guests_only_; | 1120 return is_for_guests_only_; |
1118 } | 1121 } |
1119 | 1122 |
1120 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { | 1123 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { |
1121 return storage_partition_impl_; | 1124 return storage_partition_impl_; |
1122 } | 1125 } |
1123 | 1126 |
1124 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { | 1127 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { |
1125 if (IsPropertyTreeVerificationEnabled()) | 1128 if (IsPropertyTreeVerificationEnabled()) |
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2128 | 2131 |
2129 RendererClosedDetails details(status, exit_code); | 2132 RendererClosedDetails details(status, exit_code); |
2130 mojo_application_host_->WillDestroySoon(); | 2133 mojo_application_host_->WillDestroySoon(); |
2131 | 2134 |
2132 child_process_launcher_.reset(); | 2135 child_process_launcher_.reset(); |
2133 channel_.reset(); | 2136 channel_.reset(); |
2134 while (!queued_messages_.empty()) { | 2137 while (!queued_messages_.empty()) { |
2135 delete queued_messages_.front(); | 2138 delete queued_messages_.front(); |
2136 queued_messages_.pop(); | 2139 queued_messages_.pop(); |
2137 } | 2140 } |
| 2141 UpdateProcessPriority(); |
| 2142 DCHECK(!is_process_backgrounded_); |
2138 | 2143 |
2139 within_process_died_observer_ = true; | 2144 within_process_died_observer_ = true; |
2140 NotificationService::current()->Notify( | 2145 NotificationService::current()->Notify( |
2141 NOTIFICATION_RENDERER_PROCESS_CLOSED, | 2146 NOTIFICATION_RENDERER_PROCESS_CLOSED, |
2142 Source<RenderProcessHost>(this), | 2147 Source<RenderProcessHost>(this), |
2143 Details<RendererClosedDetails>(&details)); | 2148 Details<RendererClosedDetails>(&details)); |
2144 FOR_EACH_OBSERVER(RenderProcessHostObserver, | 2149 FOR_EACH_OBSERVER(RenderProcessHostObserver, |
2145 observers_, | 2150 observers_, |
2146 RenderProcessExited(this, status, exit_code)); | 2151 RenderProcessExited(this, status, exit_code)); |
2147 within_process_died_observer_ = false; | 2152 within_process_died_observer_ = false; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2245 | 2250 |
2246 mojo_application_host_->WillDestroySoon(); | 2251 mojo_application_host_->WillDestroySoon(); |
2247 | 2252 |
2248 Send(new ChildProcessMsg_Shutdown()); | 2253 Send(new ChildProcessMsg_Shutdown()); |
2249 } | 2254 } |
2250 | 2255 |
2251 void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) { | 2256 void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) { |
2252 SetSuddenTerminationAllowed(enabled); | 2257 SetSuddenTerminationAllowed(enabled); |
2253 } | 2258 } |
2254 | 2259 |
2255 void RenderProcessHostImpl::SetBackgrounded(bool backgrounded) { | 2260 void RenderProcessHostImpl::UpdateProcessPriority() { |
2256 TRACE_EVENT1("renderer_host", "RenderProcessHostImpl::SetBackgrounded", | 2261 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting()) { |
2257 "backgrounded", backgrounded); | 2262 is_process_backgrounded_ = false; |
2258 // Note: we always set the backgrounded_ value. If the process is NULL | 2263 return; |
2259 // (and hence hasn't been created yet), we will set the process priority | 2264 } |
2260 // later when we create the process. | 2265 |
2261 backgrounded_ = backgrounded; | 2266 // 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()) | 2267 // visible widgets -- the callers must call this function whenever we |
| 2268 // transition in/out of those states. |
| 2269 const bool should_background = |
| 2270 visible_widgets_ == 0 && !audio_renderer_host_->HasActiveAudio() && |
| 2271 !base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 2272 switches::kDisableRendererBackgrounding); |
| 2273 |
| 2274 if (is_process_backgrounded_ == should_background) |
2263 return; | 2275 return; |
2264 | 2276 |
2265 // Don't background processes which have active audio streams. | 2277 TRACE_EVENT1("renderer_host", "RenderProcessHostImpl::UpdateProcessPriority", |
2266 if (backgrounded_ && audio_renderer_host_->HasActiveAudio()) | 2278 "should_background", should_background); |
2267 return; | 2279 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 | 2280 |
2274 #if defined(OS_WIN) | 2281 #if defined(OS_WIN) |
2275 // The cbstext.dll loads as a global GetMessage hook in the browser process | 2282 // The cbstext.dll loads as a global GetMessage hook in the browser process |
2276 // and intercepts/unintercepts the kernel32 API SetPriorityClass in a | 2283 // and intercepts/unintercepts the kernel32 API SetPriorityClass in a |
2277 // background thread. If the UI thread invokes this API just when it is | 2284 // 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 | 2285 // intercepted the stack is messed up on return from the interceptor |
2279 // which causes random crashes in the browser process. Our hack for now | 2286 // 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. | 2287 // is to not invoke the SetPriorityClass API if the dll is loaded. |
2281 if (GetModuleHandle(L"cbstext.dll")) | 2288 if (GetModuleHandle(L"cbstext.dll")) |
2282 return; | 2289 return; |
2283 #endif // OS_WIN | 2290 #endif // OS_WIN |
2284 | 2291 |
2285 #if defined(OS_WIN) || defined(OS_MACOSX) | 2292 #if defined(OS_WIN) || defined(OS_MACOSX) |
2286 // Same as below, but bound to an experiment (http://crbug.com/458594 on | 2293 // 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 | 2294 // 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. | 2295 // absence of field trials to get coverage on the perf waterfall. |
2289 base::FieldTrial* trial = | 2296 base::FieldTrial* trial = |
2290 base::FieldTrialList::Find("BackgroundRendererProcesses"); | 2297 base::FieldTrialList::Find("BackgroundRendererProcesses"); |
2291 if (!trial || !base::StartsWith(trial->group_name(), "Disallow", | 2298 if (!trial || !base::StartsWith(trial->group_name(), "Disallow", |
2292 base::CompareCase::SENSITIVE)) { | 2299 base::CompareCase::SENSITIVE)) { |
2293 child_process_launcher_->SetProcessBackgrounded(backgrounded); | 2300 child_process_launcher_->SetProcessBackgrounded(should_background); |
2294 } | 2301 } |
2295 #else | 2302 #else |
2296 // Control the background state from the browser process, otherwise the task | 2303 // Control the background state from the browser process, otherwise the task |
2297 // telling the renderer to "unbackground" itself may be preempted by other | 2304 // 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 | 2305 // tasks executing at lowered priority ahead of it or simply by not being |
2299 // swiftly scheduled by the OS per the low process priority | 2306 // swiftly scheduled by the OS per the low process priority |
2300 // (http://crbug.com/398103). | 2307 // (http://crbug.com/398103). |
2301 child_process_launcher_->SetProcessBackgrounded(backgrounded); | 2308 child_process_launcher_->SetProcessBackgrounded(should_background); |
2302 #endif // OS_WIN | 2309 #endif // OS_WIN |
2303 | 2310 |
2304 // Notify the child process of background state. | 2311 // Notify the child process of background state. |
2305 Send(new ChildProcessMsg_SetProcessBackgrounded(backgrounded)); | 2312 Send(new ChildProcessMsg_SetProcessBackgrounded(should_background)); |
2306 } | 2313 } |
2307 | 2314 |
2308 void RenderProcessHostImpl::OnProcessLaunched() { | 2315 void RenderProcessHostImpl::OnProcessLaunched() { |
2309 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 | 2316 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 |
2310 // is fixed. | 2317 // is fixed. |
2311 tracked_objects::ScopedTracker tracking_profile1( | 2318 tracked_objects::ScopedTracker tracking_profile1( |
2312 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2319 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
2313 "465841 RenderProcessHostImpl::OnProcessLaunched::Start")); | 2320 "465841 RenderProcessHostImpl::OnProcessLaunched::Start")); |
2314 // No point doing anything, since this object will be destructed soon. We | 2321 // No point doing anything, since this object will be destructed soon. We |
2315 // especially don't want to send the RENDERER_PROCESS_CREATED notification, | 2322 // especially don't want to send the RENDERER_PROCESS_CREATED notification, |
2316 // since some clients might expect a RENDERER_PROCESS_TERMINATED afterwards to | 2323 // since some clients might expect a RENDERER_PROCESS_TERMINATED afterwards to |
2317 // properly cleanup. | 2324 // properly cleanup. |
2318 if (deleting_soon_) | 2325 if (deleting_soon_) |
2319 return; | 2326 return; |
2320 | 2327 |
2321 if (child_process_launcher_) { | 2328 if (child_process_launcher_) { |
2322 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 | 2329 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 |
2323 // is fixed. | 2330 // is fixed. |
2324 tracked_objects::ScopedTracker tracking_profile2( | 2331 tracked_objects::ScopedTracker tracking_profile2( |
2325 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2332 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
2326 "465841 RenderProcessHostImpl::OnProcessLaunched::Backgrounded")); | 2333 "465841 RenderProcessHostImpl::OnProcessLaunched::Backgrounded")); |
2327 DCHECK(child_process_launcher_->GetProcess().IsValid()); | 2334 DCHECK(child_process_launcher_->GetProcess().IsValid()); |
2328 SetBackgrounded(backgrounded_); | 2335 DCHECK(!is_process_backgrounded_); |
| 2336 UpdateProcessPriority(); |
2329 } | 2337 } |
2330 | 2338 |
2331 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 | 2339 // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/465841 |
2332 // is fixed. | 2340 // is fixed. |
2333 tracked_objects::ScopedTracker tracking_profile3( | 2341 tracked_objects::ScopedTracker tracking_profile3( |
2334 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 2342 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
2335 "465841 RenderProcessHostImpl::OnProcessLaunched::Notify")); | 2343 "465841 RenderProcessHostImpl::OnProcessLaunched::Notify")); |
2336 // NOTE: This needs to be before sending queued messages because | 2344 // NOTE: This needs to be before sending queued messages because |
2337 // ExtensionService uses this notification to initialize the renderer process | 2345 // ExtensionService uses this notification to initialize the renderer process |
2338 // with state that must be there before any JavaScript executes. | 2346 // 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( | 2536 void RenderProcessHostImpl::GetAudioOutputControllers( |
2529 const GetAudioOutputControllersCallback& callback) const { | 2537 const GetAudioOutputControllersCallback& callback) const { |
2530 audio_renderer_host()->GetOutputControllers(callback); | 2538 audio_renderer_host()->GetOutputControllers(callback); |
2531 } | 2539 } |
2532 | 2540 |
2533 BluetoothDispatcherHost* RenderProcessHostImpl::GetBluetoothDispatcherHost() { | 2541 BluetoothDispatcherHost* RenderProcessHostImpl::GetBluetoothDispatcherHost() { |
2534 return bluetooth_dispatcher_host_.get(); | 2542 return bluetooth_dispatcher_host_.get(); |
2535 } | 2543 } |
2536 | 2544 |
2537 } // namespace content | 2545 } // namespace content |
OLD | NEW |