OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 #include "content/browser/browser_child_process_host_impl.h" | 5 #include "content/browser/browser_child_process_host_impl.h" |
6 | 6 |
7 #include "base/base_switches.h" | 7 #include "base/base_switches.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 | 73 |
74 // static | 74 // static |
75 BrowserChildProcessHostImpl::BrowserChildProcessList* | 75 BrowserChildProcessHostImpl::BrowserChildProcessList* |
76 BrowserChildProcessHostImpl::GetIterator() { | 76 BrowserChildProcessHostImpl::GetIterator() { |
77 return g_child_process_list.Pointer(); | 77 return g_child_process_list.Pointer(); |
78 } | 78 } |
79 | 79 |
80 // static | 80 // static |
81 void BrowserChildProcessHostImpl::AddObserver( | 81 void BrowserChildProcessHostImpl::AddObserver( |
82 BrowserChildProcessObserver* observer) { | 82 BrowserChildProcessObserver* observer) { |
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 83 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
84 g_observers.Get().AddObserver(observer); | 84 g_observers.Get().AddObserver(observer); |
85 } | 85 } |
86 | 86 |
87 // static | 87 // static |
88 void BrowserChildProcessHostImpl::RemoveObserver( | 88 void BrowserChildProcessHostImpl::RemoveObserver( |
89 BrowserChildProcessObserver* observer) { | 89 BrowserChildProcessObserver* observer) { |
90 // TODO(phajdan.jr): Check thread after fixing http://crbug.com/167126. | 90 // TODO(phajdan.jr): Check thread after fixing http://crbug.com/167126. |
91 g_observers.Get().RemoveObserver(observer); | 91 g_observers.Get().RemoveObserver(observer); |
92 } | 92 } |
93 | 93 |
(...skipping 15 matching lines...) Expand all Loading... |
109 | 109 |
110 power_monitor_message_broadcaster_.Init(); | 110 power_monitor_message_broadcaster_.Init(); |
111 } | 111 } |
112 | 112 |
113 BrowserChildProcessHostImpl::~BrowserChildProcessHostImpl() { | 113 BrowserChildProcessHostImpl::~BrowserChildProcessHostImpl() { |
114 g_child_process_list.Get().remove(this); | 114 g_child_process_list.Get().remove(this); |
115 } | 115 } |
116 | 116 |
117 // static | 117 // static |
118 void BrowserChildProcessHostImpl::TerminateAll() { | 118 void BrowserChildProcessHostImpl::TerminateAll() { |
119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 119 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
120 // Make a copy since the BrowserChildProcessHost dtor mutates the original | 120 // Make a copy since the BrowserChildProcessHost dtor mutates the original |
121 // list. | 121 // list. |
122 BrowserChildProcessList copy = g_child_process_list.Get(); | 122 BrowserChildProcessList copy = g_child_process_list.Get(); |
123 for (BrowserChildProcessList::iterator it = copy.begin(); | 123 for (BrowserChildProcessList::iterator it = copy.begin(); |
124 it != copy.end(); ++it) { | 124 it != copy.end(); ++it) { |
125 delete (*it)->delegate(); // ~*HostDelegate deletes *HostImpl. | 125 delete (*it)->delegate(); // ~*HostDelegate deletes *HostImpl. |
126 } | 126 } |
127 } | 127 } |
128 | 128 |
129 void BrowserChildProcessHostImpl::Launch( | 129 void BrowserChildProcessHostImpl::Launch( |
130 SandboxedProcessLauncherDelegate* delegate, | 130 SandboxedProcessLauncherDelegate* delegate, |
131 base::CommandLine* cmd_line) { | 131 base::CommandLine* cmd_line) { |
132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 132 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
133 | 133 |
134 GetContentClient()->browser()->AppendExtraCommandLineSwitches( | 134 GetContentClient()->browser()->AppendExtraCommandLineSwitches( |
135 cmd_line, data_.id); | 135 cmd_line, data_.id); |
136 | 136 |
137 const base::CommandLine& browser_command_line = | 137 const base::CommandLine& browser_command_line = |
138 *base::CommandLine::ForCurrentProcess(); | 138 *base::CommandLine::ForCurrentProcess(); |
139 static const char* kForwardSwitches[] = { | 139 static const char* kForwardSwitches[] = { |
140 switches::kDisableLogging, | 140 switches::kDisableLogging, |
141 switches::kEnableLogging, | 141 switches::kEnableLogging, |
142 switches::kIPCConnectionTimeout, | 142 switches::kIPCConnectionTimeout, |
143 switches::kLoggingLevel, | 143 switches::kLoggingLevel, |
144 switches::kTraceToConsole, | 144 switches::kTraceToConsole, |
145 switches::kV, | 145 switches::kV, |
146 switches::kVModule, | 146 switches::kVModule, |
147 }; | 147 }; |
148 cmd_line->CopySwitchesFrom(browser_command_line, kForwardSwitches, | 148 cmd_line->CopySwitchesFrom(browser_command_line, kForwardSwitches, |
149 arraysize(kForwardSwitches)); | 149 arraysize(kForwardSwitches)); |
150 | 150 |
151 child_process_.reset(new ChildProcessLauncher( | 151 child_process_.reset(new ChildProcessLauncher( |
152 delegate, | 152 delegate, |
153 cmd_line, | 153 cmd_line, |
154 data_.id, | 154 data_.id, |
155 this)); | 155 this)); |
156 } | 156 } |
157 | 157 |
158 const ChildProcessData& BrowserChildProcessHostImpl::GetData() const { | 158 const ChildProcessData& BrowserChildProcessHostImpl::GetData() const { |
159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 159 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
160 return data_; | 160 return data_; |
161 } | 161 } |
162 | 162 |
163 ChildProcessHost* BrowserChildProcessHostImpl::GetHost() const { | 163 ChildProcessHost* BrowserChildProcessHostImpl::GetHost() const { |
164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 164 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
165 return child_process_host_.get(); | 165 return child_process_host_.get(); |
166 } | 166 } |
167 | 167 |
168 const base::Process& BrowserChildProcessHostImpl::GetProcess() const { | 168 const base::Process& BrowserChildProcessHostImpl::GetProcess() const { |
169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 169 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
170 DCHECK(child_process_.get()) | 170 DCHECK(child_process_.get()) |
171 << "Requesting a child process handle before launching."; | 171 << "Requesting a child process handle before launching."; |
172 DCHECK(child_process_->GetProcess().IsValid()) | 172 DCHECK(child_process_->GetProcess().IsValid()) |
173 << "Requesting a child process handle before launch has completed OK."; | 173 << "Requesting a child process handle before launch has completed OK."; |
174 return child_process_->GetProcess(); | 174 return child_process_->GetProcess(); |
175 } | 175 } |
176 | 176 |
177 void BrowserChildProcessHostImpl::SetName(const base::string16& name) { | 177 void BrowserChildProcessHostImpl::SetName(const base::string16& name) { |
178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 178 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
179 data_.name = name; | 179 data_.name = name; |
180 } | 180 } |
181 | 181 |
182 void BrowserChildProcessHostImpl::SetHandle(base::ProcessHandle handle) { | 182 void BrowserChildProcessHostImpl::SetHandle(base::ProcessHandle handle) { |
183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 183 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
184 data_.handle = handle; | 184 data_.handle = handle; |
185 } | 185 } |
186 | 186 |
187 void BrowserChildProcessHostImpl::ForceShutdown() { | 187 void BrowserChildProcessHostImpl::ForceShutdown() { |
188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 188 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
189 g_child_process_list.Get().remove(this); | 189 g_child_process_list.Get().remove(this); |
190 child_process_host_->ForceShutdown(); | 190 child_process_host_->ForceShutdown(); |
191 } | 191 } |
192 | 192 |
193 void BrowserChildProcessHostImpl::SetBackgrounded(bool backgrounded) { | 193 void BrowserChildProcessHostImpl::SetBackgrounded(bool backgrounded) { |
194 child_process_->SetProcessBackgrounded(backgrounded); | 194 child_process_->SetProcessBackgrounded(backgrounded); |
195 } | 195 } |
196 | 196 |
197 void BrowserChildProcessHostImpl::SetTerminateChildOnShutdown( | 197 void BrowserChildProcessHostImpl::SetTerminateChildOnShutdown( |
198 bool terminate_on_shutdown) { | 198 bool terminate_on_shutdown) { |
199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 199 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
200 child_process_->SetTerminateChildOnShutdown(terminate_on_shutdown); | 200 child_process_->SetTerminateChildOnShutdown(terminate_on_shutdown); |
201 } | 201 } |
202 | 202 |
203 void BrowserChildProcessHostImpl::AddFilter(BrowserMessageFilter* filter) { | 203 void BrowserChildProcessHostImpl::AddFilter(BrowserMessageFilter* filter) { |
204 child_process_host_->AddFilter(filter->GetFilter()); | 204 child_process_host_->AddFilter(filter->GetFilter()); |
205 } | 205 } |
206 | 206 |
207 void BrowserChildProcessHostImpl::NotifyProcessInstanceCreated( | 207 void BrowserChildProcessHostImpl::NotifyProcessInstanceCreated( |
208 const ChildProcessData& data) { | 208 const ChildProcessData& data) { |
209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 209 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
210 FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(), | 210 FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(), |
211 BrowserChildProcessInstanceCreated(data)); | 211 BrowserChildProcessInstanceCreated(data)); |
212 } | 212 } |
213 | 213 |
214 void BrowserChildProcessHostImpl::HistogramBadMessageTerminated( | 214 void BrowserChildProcessHostImpl::HistogramBadMessageTerminated( |
215 int process_type) { | 215 int process_type) { |
216 UMA_HISTOGRAM_ENUMERATION("ChildProcess.BadMessgeTerminated", process_type, | 216 UMA_HISTOGRAM_ENUMERATION("ChildProcess.BadMessgeTerminated", process_type, |
217 PROCESS_TYPE_MAX); | 217 PROCESS_TYPE_MAX); |
218 } | 218 } |
219 | 219 |
220 base::TerminationStatus BrowserChildProcessHostImpl::GetTerminationStatus( | 220 base::TerminationStatus BrowserChildProcessHostImpl::GetTerminationStatus( |
221 bool known_dead, int* exit_code) { | 221 bool known_dead, int* exit_code) { |
222 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 222 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
223 if (!child_process_) // If the delegate doesn't use Launch() helper. | 223 if (!child_process_) // If the delegate doesn't use Launch() helper. |
224 return base::GetTerminationStatus(data_.handle, exit_code); | 224 return base::GetTerminationStatus(data_.handle, exit_code); |
225 return child_process_->GetChildTerminationStatus(known_dead, | 225 return child_process_->GetChildTerminationStatus(known_dead, |
226 exit_code); | 226 exit_code); |
227 } | 227 } |
228 | 228 |
229 bool BrowserChildProcessHostImpl::OnMessageReceived( | 229 bool BrowserChildProcessHostImpl::OnMessageReceived( |
230 const IPC::Message& message) { | 230 const IPC::Message& message) { |
231 return delegate_->OnMessageReceived(message); | 231 return delegate_->OnMessageReceived(message); |
232 } | 232 } |
233 | 233 |
234 void BrowserChildProcessHostImpl::OnChannelConnected(int32 peer_pid) { | 234 void BrowserChildProcessHostImpl::OnChannelConnected(int32 peer_pid) { |
235 #if defined(OS_WIN) | 235 #if defined(OS_WIN) |
236 // From this point onward, the exit of the child process is detected by an | 236 // From this point onward, the exit of the child process is detected by an |
237 // error on the IPC channel. | 237 // error on the IPC channel. |
238 early_exit_watcher_.StopWatching(); | 238 early_exit_watcher_.StopWatching(); |
239 #endif | 239 #endif |
240 | 240 |
241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 241 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
242 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 242 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
243 base::Bind(&NotifyProcessHostConnected, data_)); | 243 base::Bind(&NotifyProcessHostConnected, data_)); |
244 | 244 |
245 delegate_->OnChannelConnected(peer_pid); | 245 delegate_->OnChannelConnected(peer_pid); |
246 } | 246 } |
247 | 247 |
248 void BrowserChildProcessHostImpl::OnChannelError() { | 248 void BrowserChildProcessHostImpl::OnChannelError() { |
249 delegate_->OnChannelError(); | 249 delegate_->OnChannelError(); |
250 } | 250 } |
251 | 251 |
252 void BrowserChildProcessHostImpl::OnBadMessageReceived( | 252 void BrowserChildProcessHostImpl::OnBadMessageReceived( |
253 const IPC::Message& message) { | 253 const IPC::Message& message) { |
254 HistogramBadMessageTerminated(data_.process_type); | 254 HistogramBadMessageTerminated(data_.process_type); |
255 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 255 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
256 switches::kDisableKillAfterBadIPC)) { | 256 switches::kDisableKillAfterBadIPC)) { |
257 return; | 257 return; |
258 } | 258 } |
259 base::KillProcess(child_process_->GetProcess().Handle(), | 259 base::KillProcess(child_process_->GetProcess().Handle(), |
260 RESULT_CODE_KILLED_BAD_MESSAGE, false); | 260 RESULT_CODE_KILLED_BAD_MESSAGE, false); |
261 } | 261 } |
262 | 262 |
263 bool BrowserChildProcessHostImpl::CanShutdown() { | 263 bool BrowserChildProcessHostImpl::CanShutdown() { |
264 return delegate_->CanShutdown(); | 264 return delegate_->CanShutdown(); |
265 } | 265 } |
266 | 266 |
267 void BrowserChildProcessHostImpl::OnChildDisconnected() { | 267 void BrowserChildProcessHostImpl::OnChildDisconnected() { |
268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 268 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
269 #if defined(OS_WIN) | 269 #if defined(OS_WIN) |
270 // OnChildDisconnected may be called without OnChannelConnected, so stop the | 270 // OnChildDisconnected may be called without OnChannelConnected, so stop the |
271 // early exit watcher so GetTerminationStatus can close the process handle. | 271 // early exit watcher so GetTerminationStatus can close the process handle. |
272 early_exit_watcher_.StopWatching(); | 272 early_exit_watcher_.StopWatching(); |
273 #endif | 273 #endif |
274 if (child_process_.get() || data_.handle) { | 274 if (child_process_.get() || data_.handle) { |
275 int exit_code; | 275 int exit_code; |
276 base::TerminationStatus status = GetTerminationStatus( | 276 base::TerminationStatus status = GetTerminationStatus( |
277 true /* known_dead */, &exit_code); | 277 true /* known_dead */, &exit_code); |
278 switch (status) { | 278 switch (status) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 | 345 |
346 #if defined(OS_WIN) | 346 #if defined(OS_WIN) |
347 | 347 |
348 void BrowserChildProcessHostImpl::OnObjectSignaled(HANDLE object) { | 348 void BrowserChildProcessHostImpl::OnObjectSignaled(HANDLE object) { |
349 OnChildDisconnected(); | 349 OnChildDisconnected(); |
350 } | 350 } |
351 | 351 |
352 #endif | 352 #endif |
353 | 353 |
354 } // namespace content | 354 } // namespace content |
OLD | NEW |