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 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 |