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/file_path.h" | 10 #include "base/file_path.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "content/public/browser/content_browser_client.h" | 27 #include "content/public/browser/content_browser_client.h" |
28 #include "content/public/browser/notification_service.h" | 28 #include "content/public/browser/notification_service.h" |
29 #include "content/public/browser/notification_types.h" | 29 #include "content/public/browser/notification_types.h" |
30 #include "content/public/common/content_switches.h" | 30 #include "content/public/common/content_switches.h" |
31 #include "content/public/common/result_codes.h" | 31 #include "content/public/common/result_codes.h" |
32 | 32 |
33 #if defined(OS_MACOSX) | 33 #if defined(OS_MACOSX) |
34 #include "content/browser/mach_broker_mac.h" | 34 #include "content/browser/mach_broker_mac.h" |
35 #endif | 35 #endif |
36 | 36 |
37 using content::BrowserChildProcessHostDelegate; | 37 namespace content { |
38 using content::BrowserThread; | |
39 using content::ChildProcessData; | |
40 using content::ChildProcessHost; | |
41 using content::ChildProcessHostImpl; | |
42 | |
43 namespace { | 38 namespace { |
44 | 39 |
45 static base::LazyInstance<BrowserChildProcessHostImpl::BrowserChildProcessList> | 40 static base::LazyInstance<BrowserChildProcessHostImpl::BrowserChildProcessList> |
46 g_child_process_list = LAZY_INSTANCE_INITIALIZER; | 41 g_child_process_list = LAZY_INSTANCE_INITIALIZER; |
47 | 42 |
48 // Helper functions since the child process related notifications happen on the | 43 // Helper functions since the child process related notifications happen on the |
49 // UI thread. | 44 // UI thread. |
50 void ChildNotificationHelper(int notification_type, | 45 void ChildNotificationHelper(int notification_type, |
51 const ChildProcessData& data) { | 46 const ChildProcessData& data) { |
52 content::NotificationService::current()-> | 47 NotificationService::current()->Notify( |
53 Notify(notification_type, content::NotificationService::AllSources(), | 48 notification_type, NotificationService::AllSources(), |
54 content::Details<const ChildProcessData>(&data)); | 49 Details<const ChildProcessData>(&data)); |
55 } | 50 } |
56 | 51 |
57 } // namespace | 52 } // namespace |
58 | 53 |
59 namespace content { | |
60 | |
61 BrowserChildProcessHost* BrowserChildProcessHost::Create( | 54 BrowserChildProcessHost* BrowserChildProcessHost::Create( |
62 ProcessType type, | 55 ProcessType type, |
63 BrowserChildProcessHostDelegate* delegate) { | 56 BrowserChildProcessHostDelegate* delegate) { |
64 return new BrowserChildProcessHostImpl(type, delegate); | 57 return new BrowserChildProcessHostImpl(type, delegate); |
65 } | 58 } |
66 | 59 |
67 #if defined(OS_MACOSX) | 60 #if defined(OS_MACOSX) |
68 base::ProcessMetrics::PortProvider* BrowserChildProcessHost::GetPortProvider() { | 61 base::ProcessMetrics::PortProvider* BrowserChildProcessHost::GetPortProvider() { |
69 return MachBroker::GetInstance(); | 62 return MachBroker::GetInstance(); |
70 } | 63 } |
71 #endif | 64 #endif |
72 | 65 |
73 } // namespace content | |
74 | |
75 BrowserChildProcessHostImpl::BrowserChildProcessList* | 66 BrowserChildProcessHostImpl::BrowserChildProcessList* |
76 BrowserChildProcessHostImpl::GetIterator() { | 67 BrowserChildProcessHostImpl::GetIterator() { |
77 return g_child_process_list.Pointer(); | 68 return g_child_process_list.Pointer(); |
78 } | 69 } |
79 | 70 |
80 BrowserChildProcessHostImpl::BrowserChildProcessHostImpl( | 71 BrowserChildProcessHostImpl::BrowserChildProcessHostImpl( |
81 content::ProcessType type, | 72 ProcessType type, |
82 BrowserChildProcessHostDelegate* delegate) | 73 BrowserChildProcessHostDelegate* delegate) |
83 : data_(type), | 74 : data_(type), |
84 delegate_(delegate) { | 75 delegate_(delegate) { |
85 data_.id = ChildProcessHostImpl::GenerateChildProcessUniqueId(); | 76 data_.id = ChildProcessHostImpl::GenerateChildProcessUniqueId(); |
86 | 77 |
87 child_process_host_.reset(ChildProcessHost::Create(this)); | 78 child_process_host_.reset(ChildProcessHost::Create(this)); |
88 child_process_host_->AddFilter(new TraceMessageFilter); | 79 child_process_host_->AddFilter(new TraceMessageFilter); |
89 child_process_host_->AddFilter(new content::ProfilerMessageFilter(type)); | 80 child_process_host_->AddFilter(new ProfilerMessageFilter(type)); |
90 child_process_host_->AddFilter(new content::HistogramMessageFilter()); | 81 child_process_host_->AddFilter(new HistogramMessageFilter()); |
91 | 82 |
92 g_child_process_list.Get().push_back(this); | 83 g_child_process_list.Get().push_back(this); |
93 content::GetContentClient()->browser()->BrowserChildProcessHostCreated(this); | 84 GetContentClient()->browser()->BrowserChildProcessHostCreated(this); |
94 } | 85 } |
95 | 86 |
96 BrowserChildProcessHostImpl::~BrowserChildProcessHostImpl() { | 87 BrowserChildProcessHostImpl::~BrowserChildProcessHostImpl() { |
97 g_child_process_list.Get().remove(this); | 88 g_child_process_list.Get().remove(this); |
98 } | 89 } |
99 | 90 |
100 // static | 91 // static |
101 void BrowserChildProcessHostImpl::TerminateAll() { | 92 void BrowserChildProcessHostImpl::TerminateAll() { |
102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
103 // Make a copy since the BrowserChildProcessHost dtor mutates the original | 94 // Make a copy since the BrowserChildProcessHost dtor mutates the original |
104 // list. | 95 // list. |
105 BrowserChildProcessList copy = g_child_process_list.Get(); | 96 BrowserChildProcessList copy = g_child_process_list.Get(); |
106 for (BrowserChildProcessList::iterator it = copy.begin(); | 97 for (BrowserChildProcessList::iterator it = copy.begin(); |
107 it != copy.end(); ++it) { | 98 it != copy.end(); ++it) { |
108 delete (*it)->delegate(); // ~*HostDelegate deletes *HostImpl. | 99 delete (*it)->delegate(); // ~*HostDelegate deletes *HostImpl. |
109 } | 100 } |
110 } | 101 } |
111 | 102 |
112 void BrowserChildProcessHostImpl::Launch( | 103 void BrowserChildProcessHostImpl::Launch( |
113 #if defined(OS_WIN) | 104 #if defined(OS_WIN) |
114 const FilePath& exposed_dir, | 105 const FilePath& exposed_dir, |
115 #elif defined(OS_POSIX) | 106 #elif defined(OS_POSIX) |
116 bool use_zygote, | 107 bool use_zygote, |
117 const base::EnvironmentVector& environ, | 108 const base::EnvironmentVector& environ, |
118 #endif | 109 #endif |
119 CommandLine* cmd_line) { | 110 CommandLine* cmd_line) { |
120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 111 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
121 | 112 |
122 content::GetContentClient()->browser()->AppendExtraCommandLineSwitches( | 113 GetContentClient()->browser()->AppendExtraCommandLineSwitches( |
123 cmd_line, data_.id); | 114 cmd_line, data_.id); |
124 | 115 |
125 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 116 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
126 static const char* kForwardSwitches[] = { | 117 static const char* kForwardSwitches[] = { |
127 #if defined(OS_POSIX) | 118 #if defined(OS_POSIX) |
128 switches::kChildCleanExit, | 119 switches::kChildCleanExit, |
129 #endif | 120 #endif |
130 switches::kDisableLogging, | 121 switches::kDisableLogging, |
131 switches::kEnableDCHECK, | 122 switches::kEnableDCHECK, |
132 switches::kEnableLogging, | 123 switches::kEnableLogging, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 return base::GetTerminationStatus(data_.handle, exit_code); | 195 return base::GetTerminationStatus(data_.handle, exit_code); |
205 return child_process_->GetChildTerminationStatus(exit_code); | 196 return child_process_->GetChildTerminationStatus(exit_code); |
206 } | 197 } |
207 | 198 |
208 bool BrowserChildProcessHostImpl::OnMessageReceived( | 199 bool BrowserChildProcessHostImpl::OnMessageReceived( |
209 const IPC::Message& message) { | 200 const IPC::Message& message) { |
210 return delegate_->OnMessageReceived(message); | 201 return delegate_->OnMessageReceived(message); |
211 } | 202 } |
212 | 203 |
213 void BrowserChildProcessHostImpl::OnChannelConnected(int32 peer_pid) { | 204 void BrowserChildProcessHostImpl::OnChannelConnected(int32 peer_pid) { |
214 Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED); | 205 Notify(NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED); |
215 delegate_->OnChannelConnected(peer_pid); | 206 delegate_->OnChannelConnected(peer_pid); |
216 } | 207 } |
217 | 208 |
218 void BrowserChildProcessHostImpl::OnChannelError() { | 209 void BrowserChildProcessHostImpl::OnChannelError() { |
219 delegate_->OnChannelError(); | 210 delegate_->OnChannelError(); |
220 } | 211 } |
221 | 212 |
222 bool BrowserChildProcessHostImpl::CanShutdown() { | 213 bool BrowserChildProcessHostImpl::CanShutdown() { |
223 return delegate_->CanShutdown(); | 214 return delegate_->CanShutdown(); |
224 } | 215 } |
225 | 216 |
226 void BrowserChildProcessHostImpl::OnChildDisconnected() { | 217 void BrowserChildProcessHostImpl::OnChildDisconnected() { |
227 DCHECK(data_.handle != base::kNullProcessHandle); | 218 DCHECK(data_.handle != base::kNullProcessHandle); |
228 int exit_code; | 219 int exit_code; |
229 base::TerminationStatus status = GetTerminationStatus(&exit_code); | 220 base::TerminationStatus status = GetTerminationStatus(&exit_code); |
230 switch (status) { | 221 switch (status) { |
231 case base::TERMINATION_STATUS_PROCESS_CRASHED: | 222 case base::TERMINATION_STATUS_PROCESS_CRASHED: |
232 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: { | 223 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: { |
233 delegate_->OnProcessCrashed(exit_code); | 224 delegate_->OnProcessCrashed(exit_code); |
234 // Report that this child process crashed. | 225 // Report that this child process crashed. |
235 Notify(content::NOTIFICATION_CHILD_PROCESS_CRASHED); | 226 Notify(NOTIFICATION_CHILD_PROCESS_CRASHED); |
236 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed", | 227 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed", |
237 data_.type, | 228 data_.type, |
238 content::PROCESS_TYPE_MAX); | 229 PROCESS_TYPE_MAX); |
239 break; | 230 break; |
240 } | 231 } |
241 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: { | 232 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: { |
242 delegate_->OnProcessCrashed(exit_code); | 233 delegate_->OnProcessCrashed(exit_code); |
243 // Report that this child process was killed. | 234 // Report that this child process was killed. |
244 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed", | 235 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed", |
245 data_.type, | 236 data_.type, |
246 content::PROCESS_TYPE_MAX); | 237 PROCESS_TYPE_MAX); |
247 break; | 238 break; |
248 } | 239 } |
249 case base::TERMINATION_STATUS_STILL_RUNNING: { | 240 case base::TERMINATION_STATUS_STILL_RUNNING: { |
250 UMA_HISTOGRAM_ENUMERATION("ChildProcess.DisconnectedAlive", | 241 UMA_HISTOGRAM_ENUMERATION("ChildProcess.DisconnectedAlive", |
251 data_.type, | 242 data_.type, |
252 content::PROCESS_TYPE_MAX); | 243 PROCESS_TYPE_MAX); |
253 } | 244 } |
254 default: | 245 default: |
255 break; | 246 break; |
256 } | 247 } |
257 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected", | 248 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected", |
258 data_.type, | 249 data_.type, |
259 content::PROCESS_TYPE_MAX); | 250 PROCESS_TYPE_MAX); |
260 // Notify in the main loop of the disconnection. | 251 // Notify in the main loop of the disconnection. |
261 Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED); | 252 Notify(NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED); |
262 delete delegate_; // Will delete us | 253 delete delegate_; // Will delete us |
263 } | 254 } |
264 | 255 |
265 bool BrowserChildProcessHostImpl::Send(IPC::Message* message) { | 256 bool BrowserChildProcessHostImpl::Send(IPC::Message* message) { |
266 return child_process_host_->Send(message); | 257 return child_process_host_->Send(message); |
267 } | 258 } |
268 | 259 |
269 void BrowserChildProcessHostImpl::OnProcessLaunched() { | 260 void BrowserChildProcessHostImpl::OnProcessLaunched() { |
270 if (!child_process_->GetHandle()) { | 261 if (!child_process_->GetHandle()) { |
271 delete delegate_; // Will delete us | 262 delete delegate_; // Will delete us |
272 return; | 263 return; |
273 } | 264 } |
274 data_.handle = child_process_->GetHandle(); | 265 data_.handle = child_process_->GetHandle(); |
275 delegate_->OnProcessLaunched(); | 266 delegate_->OnProcessLaunched(); |
276 } | 267 } |
| 268 |
| 269 } // namespace content |
OLD | NEW |