blob: f2b4f8069b90b242e226e3305b090843dce6df5c [file] [log] [blame]
[email protected]02798a982012-01-27 00:45:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]d27893f62010-07-03 05:47:422// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]4c01d4992012-01-23 23:33:015#include "content/browser/browser_child_process_host_impl.h"
[email protected]d27893f62010-07-03 05:47:426
[email protected]2b065f82012-10-18 07:11:167#include "base/base_switches.h"
[email protected]4306c3792011-12-02 01:57:538#include "base/bind.h"
[email protected]d27893f62010-07-03 05:47:429#include "base/command_line.h"
wfhaf32d0b2015-04-07 02:21:3610#include "base/debug/dump_without_crashing.h"
[email protected]57999812013-02-24 05:40:5211#include "base/files/file_path.h"
[email protected]d3c6c0d72010-12-09 08:15:0412#include "base/lazy_instance.h"
[email protected]d27893f62010-07-03 05:47:4213#include "base/logging.h"
avib7348942015-12-25 20:57:1014#include "base/macros.h"
[email protected]835d7c82010-10-14 04:38:3815#include "base/metrics/histogram.h"
[email protected]7286e3fc2011-07-19 22:13:2416#include "base/stl_util.h"
[email protected]10994d132013-06-11 07:16:1817#include "base/strings/string_util.h"
[email protected]162a9fd2013-03-06 20:47:4918#include "base/synchronization/waitable_event.h"
avib7348942015-12-25 20:57:1019#include "build/build_config.h"
zhenwc5db2a02015-12-11 23:31:4320#include "components/tracing/tracing_switches.h"
[email protected]83ab4a282012-07-12 18:19:4521#include "content/browser/histogram_message_filter.h"
[email protected]678c0362012-12-05 08:02:4422#include "content/browser/loader/resource_message_filter.h"
petrcermak29bd4052015-09-24 08:28:4823#include "content/browser/memory/memory_message_filter.h"
[email protected]33047f12011-12-01 23:20:2024#include "content/browser/profiler_message_filter.h"
[email protected]3a85b1f2013-02-01 04:47:4025#include "content/browser/tracing/trace_message_filter.h"
[email protected]4734d0b2011-12-03 07:10:4426#include "content/common/child_process_host_impl.h"
John Abd-El-Malekfbada2c2015-11-24 06:38:1527#include "content/common/child_process_messages.h"
[email protected]4967f792012-01-20 22:14:4028#include "content/public/browser/browser_child_process_host_delegate.h"
[email protected]f4eaf7b92013-02-28 22:00:4029#include "content/public/browser/browser_child_process_observer.h"
[email protected]57999812013-02-24 05:40:5230#include "content/public/browser/browser_thread.h"
[email protected]4306c3792011-12-02 01:57:5331#include "content/public/browser/child_process_data.h"
[email protected]87f3c082011-10-19 18:07:4432#include "content/public/browser/content_browser_client.h"
[email protected]c08950d22011-10-13 22:20:2933#include "content/public/common/content_switches.h"
[email protected]f3b357692013-03-22 05:16:1334#include "content/public/common/process_type.h"
[email protected]b39ef1cb2011-10-25 04:46:5535#include "content/public/common/result_codes.h"
erikchend8a3d9022015-10-22 20:02:0236#include "ipc/attachment_broker.h"
37#include "ipc/attachment_broker_privileged.h"
John Abd-El-Malekfbada2c2015-11-24 06:38:1538#include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
[email protected]d27893f62010-07-03 05:47:4239
[email protected]f1675202012-07-09 15:18:0040#if defined(OS_MACOSX)
[email protected]458433c2012-02-29 23:43:3941#include "content/browser/mach_broker_mac.h"
[email protected]3838ca12011-11-02 14:37:1542#endif
[email protected]a3a7e2c2011-09-16 23:07:0543
jam1288a4e2015-12-09 02:11:5344
45#if defined(MOJO_SHELL_CLIENT)
46#include "content/browser/mojo/mojo_shell_client_host.h"
47#include "content/common/mojo/mojo_shell_connection_impl.h"
48#endif
49
[email protected]130757672012-10-24 00:26:1950namespace content {
[email protected]d27893f62010-07-03 05:47:4251namespace {
52
[email protected]4c01d4992012-01-23 23:33:0153static base::LazyInstance<BrowserChildProcessHostImpl::BrowserChildProcessList>
[email protected]4967f792012-01-20 22:14:4054 g_child_process_list = LAZY_INSTANCE_INITIALIZER;
[email protected]d27893f62010-07-03 05:47:4255
brettwf2a90a22015-06-03 23:42:5456base::LazyInstance<base::ObserverList<BrowserChildProcessObserver>>
[email protected]f4eaf7b92013-02-28 22:00:4057 g_observers = LAZY_INSTANCE_INITIALIZER;
58
afakhry9cc79002015-10-22 19:25:1559void NotifyProcessLaunchedAndConnected(const ChildProcessData& data) {
60 FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(),
61 BrowserChildProcessLaunchedAndConnected(data));
62}
63
[email protected]f4eaf7b92013-02-28 22:00:4064void NotifyProcessHostConnected(const ChildProcessData& data) {
65 FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(),
66 BrowserChildProcessHostConnected(data));
67}
68
69void NotifyProcessHostDisconnected(const ChildProcessData& data) {
70 FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(),
71 BrowserChildProcessHostDisconnected(data));
72}
73
wfh22e2f4a22015-04-28 22:39:2174void NotifyProcessCrashed(const ChildProcessData& data, int exit_code) {
[email protected]f4eaf7b92013-02-28 22:00:4075 FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(),
wfh22e2f4a22015-04-28 22:39:2176 BrowserChildProcessCrashed(data, exit_code));
[email protected]4306c3792011-12-02 01:57:5377}
[email protected]d27893f62010-07-03 05:47:4278
wfhf0003292015-08-18 22:16:4679void NotifyProcessKilled(const ChildProcessData& data, int exit_code) {
80 FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(),
81 BrowserChildProcessKilled(data, exit_code));
82}
83
[email protected]d27893f62010-07-03 05:47:4284} // namespace
85
[email protected]4967f792012-01-20 22:14:4086BrowserChildProcessHost* BrowserChildProcessHost::Create(
vadimt379d7fe2015-04-01 00:09:3587 content::ProcessType process_type,
[email protected]4967f792012-01-20 22:14:4088 BrowserChildProcessHostDelegate* delegate) {
[email protected]f3b357692013-03-22 05:16:1389 return new BrowserChildProcessHostImpl(process_type, delegate);
[email protected]4967f792012-01-20 22:14:4090}
91
amistryfaa231a42015-05-20 01:49:1292BrowserChildProcessHost* BrowserChildProcessHost::FromID(int child_process_id) {
93 DCHECK_CURRENTLY_ON(BrowserThread::IO);
94 BrowserChildProcessHostImpl::BrowserChildProcessList* process_list =
95 g_child_process_list.Pointer();
96 for (BrowserChildProcessHostImpl* host : *process_list) {
97 if (host->GetData().id == child_process_id)
98 return host;
99 }
100 return nullptr;
101}
102
[email protected]458433c2012-02-29 23:43:39103#if defined(OS_MACOSX)
erikchencd3e0e7b2015-10-01 22:53:51104base::PortProvider* BrowserChildProcessHost::GetPortProvider() {
[email protected]458433c2012-02-29 23:43:39105 return MachBroker::GetInstance();
106}
107#endif
108
[email protected]f4eaf7b92013-02-28 22:00:40109// static
[email protected]4c01d4992012-01-23 23:33:01110BrowserChildProcessHostImpl::BrowserChildProcessList*
111 BrowserChildProcessHostImpl::GetIterator() {
[email protected]4967f792012-01-20 22:14:40112 return g_child_process_list.Pointer();
113}
114
[email protected]f4eaf7b92013-02-28 22:00:40115// static
116void BrowserChildProcessHostImpl::AddObserver(
117 BrowserChildProcessObserver* observer) {
mostynbfbcdc27a2015-03-13 17:58:52118 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]f4eaf7b92013-02-28 22:00:40119 g_observers.Get().AddObserver(observer);
120}
121
122// static
123void BrowserChildProcessHostImpl::RemoveObserver(
124 BrowserChildProcessObserver* observer) {
125 // TODO(phajdan.jr): Check thread after fixing http://crbug.com/167126.
126 g_observers.Get().RemoveObserver(observer);
127}
128
[email protected]4c01d4992012-01-23 23:33:01129BrowserChildProcessHostImpl::BrowserChildProcessHostImpl(
vadimt379d7fe2015-04-01 00:09:35130 content::ProcessType process_type,
[email protected]4967f792012-01-20 22:14:40131 BrowserChildProcessHostDelegate* delegate)
[email protected]f3b357692013-03-22 05:16:13132 : data_(process_type),
[email protected]9dd90152013-08-02 22:09:13133 delegate_(delegate),
afakhry9cc79002015-10-22 19:25:15134 power_monitor_message_broadcaster_(this),
135 is_channel_connected_(false) {
[email protected]4734d0b2011-12-03 07:10:44136 data_.id = ChildProcessHostImpl::GenerateChildProcessUniqueId();
[email protected]4306c3792011-12-02 01:57:53137
erikchend8a3d9022015-10-22 20:02:02138#if USE_ATTACHMENT_BROKER
139 // Construct the privileged attachment broker early in the life cycle of a
140 // child process. This ensures that when a test is being run in one of the
141 // single process modes, the global attachment broker is the privileged
142 // attachment broker, rather than an unprivileged attachment broker.
143#if defined(OS_MACOSX) && !defined(OS_IOS)
144 IPC::AttachmentBrokerPrivileged::CreateBrokerIfNeeded(
145 MachBroker::GetInstance());
146#else
147 IPC::AttachmentBrokerPrivileged::CreateBrokerIfNeeded();
148#endif // defined(OS_MACOSX) && !defined(OS_IOS)
149#endif // USE_ATTACHMENT_BROKER
150
[email protected]4734d0b2011-12-03 07:10:44151 child_process_host_.reset(ChildProcessHost::Create(this));
ssid72c5d6822015-06-26 15:51:42152 AddFilter(new TraceMessageFilter(data_.id));
[email protected]ba780c12013-10-01 17:07:06153 AddFilter(new ProfilerMessageFilter(process_type));
154 AddFilter(new HistogramMessageFilter);
chrishada753d472015-12-08 00:57:13155 AddFilter(new MemoryMessageFilter(this, process_type));
[email protected]38917fe2011-04-06 17:29:12156
157 g_child_process_list.Get().push_back(this);
[email protected]130757672012-10-24 00:26:19158 GetContentClient()->browser()->BrowserChildProcessHostCreated(this);
[email protected]30c4c67a2014-07-22 02:33:55159
160 power_monitor_message_broadcaster_.Init();
[email protected]38917fe2011-04-06 17:29:12161}
162
[email protected]4c01d4992012-01-23 23:33:01163BrowserChildProcessHostImpl::~BrowserChildProcessHostImpl() {
[email protected]d3c6c0d72010-12-09 08:15:04164 g_child_process_list.Get().remove(this);
[email protected]d27893f62010-07-03 05:47:42165}
166
167// static
[email protected]4c01d4992012-01-23 23:33:01168void BrowserChildProcessHostImpl::TerminateAll() {
mostynbfbcdc27a2015-03-13 17:58:52169 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]f174efd2012-01-17 18:43:33170 // Make a copy since the BrowserChildProcessHost dtor mutates the original
171 // list.
172 BrowserChildProcessList copy = g_child_process_list.Get();
[email protected]5998d9d2012-03-06 04:25:26173 for (BrowserChildProcessList::iterator it = copy.begin();
174 it != copy.end(); ++it) {
175 delete (*it)->delegate(); // ~*HostDelegate deletes *HostImpl.
176 }
[email protected]d27893f62010-07-03 05:47:42177}
178
[email protected]4c01d4992012-01-23 23:33:01179void BrowserChildProcessHostImpl::Launch(
[email protected]34f48682013-03-20 00:30:18180 SandboxedProcessLauncherDelegate* delegate,
sievers954e37a2015-03-28 01:50:24181 base::CommandLine* cmd_line,
182 bool terminate_on_shutdown) {
mostynbfbcdc27a2015-03-13 17:58:52183 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]b80f68432011-05-02 17:22:30184
[email protected]130757672012-10-24 00:26:19185 GetContentClient()->browser()->AppendExtraCommandLineSwitches(
[email protected]4967f792012-01-20 22:14:40186 cmd_line, data_.id);
[email protected]b80f68432011-05-02 17:22:30187
[email protected]479278702014-08-11 20:32:09188 const base::CommandLine& browser_command_line =
189 *base::CommandLine::ForCurrentProcess();
[email protected]2b065f82012-10-18 07:11:16190 static const char* kForwardSwitches[] = {
[email protected]2b065f82012-10-18 07:11:16191 switches::kDisableLogging,
[email protected]2b065f82012-10-18 07:11:16192 switches::kEnableLogging,
[email protected]65f0ff72014-06-20 20:32:15193 switches::kIPCConnectionTimeout,
[email protected]2b065f82012-10-18 07:11:16194 switches::kLoggingLevel,
[email protected]2bf64a92013-07-11 23:10:40195 switches::kTraceToConsole,
[email protected]2b065f82012-10-18 07:11:16196 switches::kV,
197 switches::kVModule,
jam76bcf0c2015-10-02 21:01:28198 "use-new-edk", // TODO(use_chrome_edk): temporary.
[email protected]2b065f82012-10-18 07:11:16199 };
200 cmd_line->CopySwitchesFrom(browser_command_line, kForwardSwitches,
201 arraysize(kForwardSwitches));
[email protected]719a2052012-07-30 21:00:43202
[email protected]d27893f62010-07-03 05:47:42203 child_process_.reset(new ChildProcessLauncher(
[email protected]34f48682013-03-20 00:30:18204 delegate,
[email protected]d27893f62010-07-03 05:47:42205 cmd_line,
[email protected]40da3e0c2012-10-24 22:03:38206 data_.id,
sievers954e37a2015-03-28 01:50:24207 this,
208 terminate_on_shutdown));
[email protected]d27893f62010-07-03 05:47:42209}
210
[email protected]4c01d4992012-01-23 23:33:01211const ChildProcessData& BrowserChildProcessHostImpl::GetData() const {
mostynbfbcdc27a2015-03-13 17:58:52212 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]4967f792012-01-20 22:14:40213 return data_;
214}
215
[email protected]4c01d4992012-01-23 23:33:01216ChildProcessHost* BrowserChildProcessHostImpl::GetHost() const {
mostynbfbcdc27a2015-03-13 17:58:52217 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]4967f792012-01-20 22:14:40218 return child_process_host_.get();
219}
220
rvargas5779b382014-11-18 20:44:11221const base::Process& BrowserChildProcessHostImpl::GetProcess() const {
mostynbfbcdc27a2015-03-13 17:58:52222 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]5d84d012010-12-02 17:17:21223 DCHECK(child_process_.get())
224 << "Requesting a child process handle before launching.";
rvargas079d1842014-10-17 22:32:16225 DCHECK(child_process_->GetProcess().IsValid())
[email protected]5d84d012010-12-02 17:17:21226 << "Requesting a child process handle before launch has completed OK.";
rvargas5779b382014-11-18 20:44:11227 return child_process_->GetProcess();
[email protected]5d84d012010-12-02 17:17:21228}
229
[email protected]fcf75d42013-12-03 20:11:26230void BrowserChildProcessHostImpl::SetName(const base::string16& name) {
mostynbfbcdc27a2015-03-13 17:58:52231 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]f174efd2012-01-17 18:43:33232 data_.name = name;
233}
234
[email protected]4c01d4992012-01-23 23:33:01235void BrowserChildProcessHostImpl::SetHandle(base::ProcessHandle handle) {
mostynbfbcdc27a2015-03-13 17:58:52236 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]f174efd2012-01-17 18:43:33237 data_.handle = handle;
238}
239
amistryfaa231a42015-05-20 01:49:12240ServiceRegistry* BrowserChildProcessHostImpl::GetServiceRegistry() {
241 DCHECK_CURRENTLY_ON(BrowserThread::IO);
242 return delegate_->GetServiceRegistry();
243}
244
[email protected]4c01d4992012-01-23 23:33:01245void BrowserChildProcessHostImpl::ForceShutdown() {
mostynbfbcdc27a2015-03-13 17:58:52246 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]d3c6c0d72010-12-09 08:15:04247 g_child_process_list.Get().remove(this);
[email protected]4cb43102011-12-02 20:24:49248 child_process_host_->ForceShutdown();
[email protected]d27893f62010-07-03 05:47:42249}
250
[email protected]d36860d2013-05-31 00:04:21251void BrowserChildProcessHostImpl::SetBackgrounded(bool backgrounded) {
252 child_process_->SetProcessBackgrounded(backgrounded);
253}
254
[email protected]ba780c12013-10-01 17:07:06255void BrowserChildProcessHostImpl::AddFilter(BrowserMessageFilter* filter) {
256 child_process_host_->AddFilter(filter->GetFilter());
257}
258
[email protected]f4eaf7b92013-02-28 22:00:40259void BrowserChildProcessHostImpl::NotifyProcessInstanceCreated(
260 const ChildProcessData& data) {
mostynbfbcdc27a2015-03-13 17:58:52261 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]f4eaf7b92013-02-28 22:00:40262 FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(),
263 BrowserChildProcessInstanceCreated(data));
[email protected]d27893f62010-07-03 05:47:42264}
265
[email protected]ef2f6ba2014-05-15 23:06:07266void BrowserChildProcessHostImpl::HistogramBadMessageTerminated(
267 int process_type) {
268 UMA_HISTOGRAM_ENUMERATION("ChildProcess.BadMessgeTerminated", process_type,
269 PROCESS_TYPE_MAX);
270}
271
[email protected]4c01d4992012-01-23 23:33:01272base::TerminationStatus BrowserChildProcessHostImpl::GetTerminationStatus(
[email protected]547603d2013-08-27 17:59:19273 bool known_dead, int* exit_code) {
mostynbfbcdc27a2015-03-13 17:58:52274 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]59383c782013-04-17 16:43:27275 if (!child_process_) // If the delegate doesn't use Launch() helper.
[email protected]4967f792012-01-20 22:14:40276 return base::GetTerminationStatus(data_.handle, exit_code);
[email protected]547603d2013-08-27 17:59:19277 return child_process_->GetChildTerminationStatus(known_dead,
[email protected]c7691de2012-12-06 08:31:51278 exit_code);
[email protected]d27893f62010-07-03 05:47:42279}
280
[email protected]4c01d4992012-01-23 23:33:01281bool BrowserChildProcessHostImpl::OnMessageReceived(
282 const IPC::Message& message) {
[email protected]4967f792012-01-20 22:14:40283 return delegate_->OnMessageReceived(message);
[email protected]4cb43102011-12-02 20:24:49284}
285
avib7348942015-12-25 20:57:10286void BrowserChildProcessHostImpl::OnChannelConnected(int32_t peer_pid) {
afakhry9cc79002015-10-22 19:25:15287 DCHECK_CURRENTLY_ON(BrowserThread::IO);
288
289 is_channel_connected_ = true;
290
[email protected]162a9fd2013-03-06 20:47:49291#if defined(OS_WIN)
292 // From this point onward, the exit of the child process is detected by an
293 // error on the IPC channel.
[email protected]162a9fd2013-03-06 20:47:49294 early_exit_watcher_.StopWatching();
295#endif
296
[email protected]f4eaf7b92013-02-28 22:00:40297 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
298 base::Bind(&NotifyProcessHostConnected, data_));
[email protected]162a9fd2013-03-06 20:47:49299
[email protected]4967f792012-01-20 22:14:40300 delegate_->OnChannelConnected(peer_pid);
afakhry9cc79002015-10-22 19:25:15301
302 if (IsProcessLaunched()) {
303 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
304 base::Bind(&NotifyProcessLaunchedAndConnected,
305 data_));
306 }
[email protected]4967f792012-01-20 22:14:40307}
308
[email protected]4c01d4992012-01-23 23:33:01309void BrowserChildProcessHostImpl::OnChannelError() {
[email protected]4967f792012-01-20 22:14:40310 delegate_->OnChannelError();
[email protected]0d6e9bd2011-10-18 04:29:16311}
312
[email protected]ef2f6ba2014-05-15 23:06:07313void BrowserChildProcessHostImpl::OnBadMessageReceived(
314 const IPC::Message& message) {
315 HistogramBadMessageTerminated(data_.process_type);
avi83883c82014-12-23 00:08:49316 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]e44d1342014-05-16 21:29:33317 switches::kDisableKillAfterBadIPC)) {
318 return;
319 }
jamescookda2505812015-03-20 18:01:18320 LOG(ERROR) << "Terminating child process for bad IPC message of type "
321 << message.type();
wfhaf32d0b2015-04-07 02:21:36322
323 // Create a memory dump. This will contain enough stack frames to work out
324 // what the bad message was.
325 base::debug::DumpWithoutCrashing();
326
rvargas486b2f562015-03-18 01:36:33327 child_process_->GetProcess().Terminate(RESULT_CODE_KILLED_BAD_MESSAGE, false);
[email protected]ef2f6ba2014-05-15 23:06:07328}
329
[email protected]4c01d4992012-01-23 23:33:01330bool BrowserChildProcessHostImpl::CanShutdown() {
[email protected]4967f792012-01-20 22:14:40331 return delegate_->CanShutdown();
[email protected]4cb43102011-12-02 20:24:49332}
333
[email protected]4c01d4992012-01-23 23:33:01334void BrowserChildProcessHostImpl::OnChildDisconnected() {
mostynbfbcdc27a2015-03-13 17:58:52335 DCHECK_CURRENTLY_ON(BrowserThread::IO);
jbauman319402e2014-10-21 17:52:21336#if defined(OS_WIN)
337 // OnChildDisconnected may be called without OnChannelConnected, so stop the
338 // early exit watcher so GetTerminationStatus can close the process handle.
339 early_exit_watcher_.StopWatching();
340#endif
[email protected]6d057a0c2013-07-09 21:12:07341 if (child_process_.get() || data_.handle) {
[email protected]6d057a0c2013-07-09 21:12:07342 int exit_code;
[email protected]547603d2013-08-27 17:59:19343 base::TerminationStatus status = GetTerminationStatus(
344 true /* known_dead */, &exit_code);
[email protected]6d057a0c2013-07-09 21:12:07345 switch (status) {
346 case base::TERMINATION_STATUS_PROCESS_CRASHED:
347 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: {
348 delegate_->OnProcessCrashed(exit_code);
wfh22e2f4a22015-04-28 22:39:21349 BrowserThread::PostTask(
350 BrowserThread::UI, FROM_HERE,
351 base::Bind(&NotifyProcessCrashed, data_, exit_code));
[email protected]6d057a0c2013-07-09 21:12:07352 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed2",
353 data_.process_type,
354 PROCESS_TYPE_MAX);
355 break;
356 }
derekjchow1b0f3bb2015-07-30 18:51:10357#if defined(OS_ANDROID)
358 case base::TERMINATION_STATUS_OOM_PROTECTED:
359#endif
oshima620225722015-06-04 19:45:27360#if defined(OS_CHROMEOS)
361 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM:
362#endif
[email protected]6d057a0c2013-07-09 21:12:07363 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: {
364 delegate_->OnProcessCrashed(exit_code);
wfhf0003292015-08-18 22:16:46365 BrowserThread::PostTask(
366 BrowserThread::UI, FROM_HERE,
367 base::Bind(&NotifyProcessKilled, data_, exit_code));
[email protected]6d057a0c2013-07-09 21:12:07368 // Report that this child process was killed.
369 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed2",
370 data_.process_type,
371 PROCESS_TYPE_MAX);
372 break;
373 }
374 case base::TERMINATION_STATUS_STILL_RUNNING: {
375 UMA_HISTOGRAM_ENUMERATION("ChildProcess.DisconnectedAlive2",
376 data_.process_type,
377 PROCESS_TYPE_MAX);
378 }
379 default:
380 break;
[email protected]12fed812011-09-16 05:47:29381 }
[email protected]6d057a0c2013-07-09 21:12:07382 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected2",
383 data_.process_type,
384 PROCESS_TYPE_MAX);
oshima620225722015-06-04 19:45:27385#if defined(OS_CHROMEOS)
386 if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM) {
387 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed2.OOM",
388 data_.process_type,
389 PROCESS_TYPE_MAX);
390 }
391#endif
[email protected]d27893f62010-07-03 05:47:42392 }
[email protected]f4eaf7b92013-02-28 22:00:40393 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
394 base::Bind(&NotifyProcessHostDisconnected, data_));
[email protected]4967f792012-01-20 22:14:40395 delete delegate_; // Will delete us
[email protected]a3a7e2c2011-09-16 23:07:05396}
397
[email protected]4c01d4992012-01-23 23:33:01398bool BrowserChildProcessHostImpl::Send(IPC::Message* message) {
[email protected]4cb43102011-12-02 20:24:49399 return child_process_host_->Send(message);
400}
401
[email protected]fa01e472014-02-11 14:45:35402void BrowserChildProcessHostImpl::OnProcessLaunchFailed() {
403 delegate_->OnProcessLaunchFailed();
404 delete delegate_; // Will delete us
405}
406
[email protected]4c01d4992012-01-23 23:33:01407void BrowserChildProcessHostImpl::OnProcessLaunched() {
afakhry9cc79002015-10-22 19:25:15408 DCHECK_CURRENTLY_ON(BrowserThread::IO);
409
rvargas079d1842014-10-17 22:32:16410 const base::Process& process = child_process_->GetProcess();
411 DCHECK(process.IsValid());
[email protected]162a9fd2013-03-06 20:47:49412
John Abd-El-Malekfbada2c2015-11-24 06:38:15413 if (base::CommandLine::ForCurrentProcess()->HasSwitch("use-new-edk")) {
jam1288a4e2015-12-09 02:11:53414 mojo::embedder::ScopedPlatformHandle client_pipe;
415#if defined(MOJO_SHELL_CLIENT)
416 if (IsRunningInMojoShell()) {
417 client_pipe = RegisterProcessWithBroker(process.Pid());
418 } else
419#endif
420 {
421 client_pipe = mojo::embedder::ChildProcessLaunched(process.Handle());
422 }
John Abd-El-Malek362d0c772015-11-24 21:29:26423 Send(new ChildProcessMsg_SetMojoParentPipeHandle(
jam3c8c50c2015-11-25 18:48:29424 IPC::GetFileHandleForProcess(
425#if defined(OS_WIN)
426 client_pipe.release().handle,
427#else
428 client_pipe.release().fd,
429#endif
430 process.Handle(), true)));
John Abd-El-Malekfbada2c2015-11-24 06:38:15431 }
432
jam3c8c50c2015-11-25 18:48:29433#if defined(OS_WIN)
[email protected]162a9fd2013-03-06 20:47:49434 // Start a WaitableEventWatcher that will invoke OnProcessExitedEarly if the
435 // child process exits. This watcher is stopped once the IPC channel is
436 // connected and the exit of the child process is detecter by an error on the
437 // IPC channel thereafter.
rvargas079d1842014-10-17 22:32:16438 DCHECK(!early_exit_watcher_.GetWatchedObject());
jam7fab1082015-09-29 02:26:18439 early_exit_watcher_.StartWatchingOnce(process.Handle(), this);
[email protected]162a9fd2013-03-06 20:47:49440#endif
441
rvargas079d1842014-10-17 22:32:16442 // TODO(rvargas) crbug.com/417532: Don't store a handle.
443 data_.handle = process.Handle();
[email protected]4967f792012-01-20 22:14:40444 delegate_->OnProcessLaunched();
afakhry9cc79002015-10-22 19:25:15445
446 if (is_channel_connected_) {
447 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
448 base::Bind(&NotifyProcessLaunchedAndConnected,
449 data_));
450 }
451}
452
453bool BrowserChildProcessHostImpl::IsProcessLaunched() const {
454 DCHECK_CURRENTLY_ON(BrowserThread::IO);
455
456 return child_process_.get() && child_process_->GetProcess().IsValid();
[email protected]d27893f62010-07-03 05:47:42457}
[email protected]130757672012-10-24 00:26:19458
[email protected]162a9fd2013-03-06 20:47:49459#if defined(OS_WIN)
460
rvargas079d1842014-10-17 22:32:16461void BrowserChildProcessHostImpl::OnObjectSignaled(HANDLE object) {
[email protected]162a9fd2013-03-06 20:47:49462 OnChildDisconnected();
463}
464
465#endif
466
[email protected]130757672012-10-24 00:26:19467} // namespace content